rodzic
a1d7816570
commit
5b7f1f5e4b
|
@ -25,3 +25,4 @@ Configuration_*.h
|
|||
Repetier.depend
|
||||
Repetier.layout
|
||||
activate*.bat
|
||||
~$Translate.xlsx
|
||||
|
|
62
.travis.yml
62
.travis.yml
|
@ -5,46 +5,40 @@ language: bash
|
|||
os:
|
||||
- linux
|
||||
|
||||
before_install:
|
||||
- "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac -screen 0 1280x1024x16"
|
||||
|
||||
env:
|
||||
matrix:
|
||||
- DAVINCI=0 MODEL=0
|
||||
- DAVINCI=1 MODEL=0
|
||||
- DAVINCI=2 MODEL=0
|
||||
- DAVINCI=3 MODEL=0
|
||||
- DAVINCI=1 MODEL=1
|
||||
- DAVINCI=2 MODEL=1
|
||||
- DAVINCI=4 MODEL=1
|
||||
|
||||
before_script:
|
||||
- "export DISPLAY=:99.0"
|
||||
- sleep 3 # give xvfb some time to start
|
||||
- wget http://downloads.arduino.cc/arduino-1.6.5-linux64.tar.xz
|
||||
- tar xf arduino-1.6.5-linux64.tar.xz
|
||||
- mv arduino-1.6.5 $HOME/arduino_ide
|
||||
- mkdir -p $HOME/.arduino15/packages/arduino/hardware/sam
|
||||
- cd $HOME/.arduino15/packages/arduino/hardware/sam
|
||||
- wget http://downloads.arduino.cc/cores/sam-1.6.4.tar.bz2
|
||||
- tar xf sam-1.6.4.tar.bz2
|
||||
- mkdir -p $HOME/.arduino15/packages/arduino/tools/arm-none-eabi-gcc
|
||||
- cd $HOME/.arduino15/packages/arduino/tools/arm-none-eabi-gcc
|
||||
- wget http://downloads.arduino.cc/gcc-arm-none-eabi-4.8.3-2014q1-linux64.tar.gz
|
||||
- tar xf gcc-arm-none-eabi-4.8.3-2014q1-linux64.tar.gz
|
||||
- mv gcc-arm-none-eabi-4.8.3-2014q1 4.8.3-2014q1
|
||||
- cp -f "$TRAVIS_BUILD_DIR/src/ArduinoDUE/AdditionalArduinoFiles/Arduino - 1.6.5 -Due 1.6.4/Arduino15/packages/hardware/sam/1.6.4/variants/arduino_due_x/variant.cpp" $HOME/.arduino15/packages/arduino/hardware/sam/1.6.4/variants/arduino_due_x/variant.cpp
|
||||
- "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16"
|
||||
- sleep 3
|
||||
- export DISPLAY=:1.0
|
||||
- wget http://downloads.arduino.cc/arduino-1.6.9-linux64.tar.xz
|
||||
- tar xf arduino-1.6.9-linux64.tar.xz
|
||||
- mv arduino-1.6.9 $HOME/arduino_ide
|
||||
- export PATH="$HOME/arduino_ide:$PATH"
|
||||
- arduino --install-boards arduino:sam:1.6.8
|
||||
- arduino --board arduino:sam:arduino_due_x --save-prefs
|
||||
- arduino --pref "compiler.warning_level=all" --save-prefs
|
||||
- cp -f "$TRAVIS_BUILD_DIR/src/ArduinoDUE/AdditionalArduinoFiles/Arduino - 1.6.9 -Due 1.6.8/Arduino15/packages/arduino/hardware/sam/1.6.8/variants/arduino_due_x/variant.cpp" $HOME/.arduino15/packages/arduino/hardware/sam/1.6.8/variants/arduino_due_x/variant.cpp
|
||||
|
||||
|
||||
script:
|
||||
- cd $TRAVIS_BUILD_DIR
|
||||
- source command.sh
|
||||
- export PATH="$HOME/arduino_ide:$PATH"
|
||||
- arduino --board arduino:sam:arduino_due_x --save-prefs
|
||||
- arduino --get-pref sketchbook.path
|
||||
- build_sketch ./src/ArduinoDUE/Repetier/Repetier.ino
|
||||
- sed -i 's/#define DAVINCI 1 /#define DAVINCI 2 /g' ./src/ArduinoDUE/Repetier/Configuration.h
|
||||
- build_sketch ./src/ArduinoDUE/Repetier/Repetier.ino
|
||||
- sed -i 's/#define DAVINCI 2 /#define DAVINCI 3 /g' ./src/ArduinoDUE/Repetier/Configuration.h
|
||||
- build_sketch ./src/ArduinoDUE/Repetier/Repetier.ino
|
||||
- sed -i 's/#define DAVINCI 3 /#define DAVINCI 0 /g' ./src/ArduinoDUE/Repetier/Configuration.h
|
||||
- build_sketch ./src/ArduinoDUE/Repetier/Repetier.ino
|
||||
- sed -i 's/#define DAVINCI 0 /#define DAVINCI 1 /g' ./src/ArduinoDUE/Repetier/Configuration.h
|
||||
- sed -i 's/#define MODEL 0/#define MODEL 1/g' ./src/ArduinoDUE/Repetier/Configuration.h
|
||||
- build_sketch ./src/ArduinoDUE/Repetier/Repetier.ino
|
||||
- sed -i 's/#define DAVINCI 1 /#define DAVINCI 3 /g' ./src/ArduinoDUE/Repetier/Configuration.h
|
||||
- build_sketch ./src/ArduinoDUE/Repetier/Repetier.ino
|
||||
- sed -i 's/#define DAVINCI 3 /#define DAVINCI 4 /g' ./src/ArduinoDUE/Repetier/Configuration.h
|
||||
- sed -i "s/#define DAVINCI 0 /#define DAVINCI $DAVINCI /g" ./src/ArduinoDUE/Repetier/Configuration.h
|
||||
- sed -i "s/#define DAVINCI 1 /#define DAVINCI $DAVINCI /g" ./src/ArduinoDUE/Repetier/Configuration.h
|
||||
- sed -i "s/#define DAVINCI 2 /#define DAVINCI $DAVINCI /g" ./src/ArduinoDUE/Repetier/Configuration.h
|
||||
- sed -i "s/#define DAVINCI 3 /#define DAVINCI $DAVINCI /g" ./src/ArduinoDUE/Repetier/Configuration.h
|
||||
- sed -i "s/#define DAVINCI 4 /#define DAVINCI $DAVINCI /g" ./src/ArduinoDUE/Repetier/Configuration.h
|
||||
- sed -i "s/#define MODEL 1/#define MODEL $MODEL/g" ./src/ArduinoDUE/Repetier/Configuration.h
|
||||
- sed -i "s/#define MODEL 0/#define MODEL $MODEL/g" ./src/ArduinoDUE/Repetier/Configuration.h
|
||||
- build_sketch ./src/ArduinoDUE/Repetier/Repetier.ino
|
||||
|
||||
notifications:
|
||||
|
|
54
README.md
54
README.md
|
@ -1,27 +1,24 @@
|
|||
##Da Vinci Firmware based on Repetier (0.92.3)
|
||||
##Da Vinci Firmware based on Repetier (0.92.10) Alpha
|
||||
============================
|
||||
|
||||
[![Join the chat at https://gitter.im/luc-github/Repetier-Firmware-0.92](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/luc-github/Repetier-Firmware-0.92?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
Ide 1.6.5 and module Due 1.6.4 : [![Build Status](https://travis-ci.org/luc-github/Repetier-Firmware-0.92.svg?branch=master)](https://travis-ci.org/luc-github/Repetier-Firmware-0.92)
|
||||
[![Join the chat at https://gitter.im/luc-github/Repetier-Firmware-0.92](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/luc-github/Repetier-Firmware-0.92?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
|
||||
Build Status: [![Build Status](https://travis-ci.org/luc-github/Repetier-Firmware-0.92.svg?branch=master)](https://travis-ci.org/luc-github/Repetier-Firmware-0.92)
|
||||
|
||||
|
||||
|
||||
This firmware is based on the popular repetier firmware and modified to work with first generation Da Vinci 1.0, 2.0 single fan, 2.0 dual fans and also AiO (NB:scanner function is not supported so AiO will work like an 1.0A)
|
||||
If you change the board, currently DUE based are supported with RADDS, as well as Graphical screen and LCD with encoder, there are some sample configuration files provided for RADDS/DUE/GLCD using 1/128 step drivers.
|
||||
|
||||
YOU MIGHT DAMAGE YOUR PRINTER OR VOID YOUR WARRANTY, DO IT ON YOUR OWN RISK. When it is possible on 1.0/2.0, currently on 1.0A/2.0A and AiO there is no way to revert to stock fw so be sure of what you are doing.
|
||||
|
||||
***
|
||||
###Support for 1.0A/2.0A/AiO(no scanner) is implemented and need feedback.
|
||||
|
||||
###:boom:New alpha version based on 0.92.10 is ready for test [here](https://github.com/luc-github/Repetier-Firmware-0.92/tree/devt)
|
||||
* Multilangue :globe_with_meridians:
|
||||
* AiO support for scanner :camera:
|
||||
* Better auto leveling :tractor:
|
||||
AiO scanner support is present in FW but scanner software support is currently basic, [horus](https://github.com/bqlabs/horus) is a good candidat, feel free to help [here](https://github.com/luc-github/Repetier-Firmware-0.92/issues/156)
|
||||
|
||||
The board can be easily exposed by removing the back panel of the printer secured by two torx screws. Supported boards have a jumper labeled JP1, second generation boards have a jumper labeled J37. More info can be found on the [Voltivo forum](http://voltivo.com/forum/davinci-peersupport/340-new-kind-of-mainboard-no-j1-erase-jumper).
|
||||
***
|
||||
|
||||
Here are just a few of the benifits of using this firmware:
|
||||
Here are just a few of the benefits of using this firmware:
|
||||
|
||||
* It works with host software such as [repetier host](http://repetier.com) and [OctoPrint](http://octoprint.org/) giving you full control of your hardware.
|
||||
* It works stand alone if you use a WIFI SD Card.
|
||||
|
@ -35,16 +32,16 @@ The previous version (based on repetier v0.91) can be found [here](https://githu
|
|||
|
||||
***
|
||||
##Current Status
|
||||
####Beta - so far so good
|
||||
####Alpha - so far so good
|
||||
|
||||
***
|
||||
##Installation
|
||||
1. With the machine off remove the back panel and short the jumper JP1 or J37 depending on model. Some Boards do not have jumper pins exposed but can still be shorted with a conductive wire.
|
||||
2. Turn the machine on and wait a few seconds then turn it off again. The machine will have been flashed removing the current stock firmware and allowing it to be detected as a normal arduino DUE. NOTE: Windows users may need to install drivers to detect the board. Consult the Voltivo forums.
|
||||
Note : points 1 and 2 are only needed to wipe the stock fw or a corrupted fw, for update they are not necessary.
|
||||
3. Use an arduino IDE supporting arduino DUE, [version 1.5.8+ or 1.6.5](http://arduino.cc/en/Main/OldSoftwareReleases), 1.6.0+ bring several issues, but 1.6.5 seems working well with Due 1.6.4 module for board manager.
|
||||
4. Update arduino files (variants.cpp and USBCore.cpp) with the one(s) present in src\ArduinoDUE\AdditionalArduinoFiles\1.5.8. or in src\ArduinoDUE\AdditionalArduinoFiles\1.6.5 according your IDE version
|
||||
NOTE: You do not need to compile arduino from source these files are in the arduino directory structure. On Mac you will need to right click on the Arduino.app to Show Package Contents.
|
||||
2. Turn the machine on and wait a few seconds then turn it off again. The machine will have been flashed removing the current stock firmware and allowing it to be detected as a normal arduino DUE. NOTE: Windows users may need to install drivers to detect the board. Consult the Voltivo forums.
|
||||
Note : points 1 and 2 are only needed to wipe the stock fw or a corrupted fw, for update they are not necessary.
|
||||
3. Use an arduino IDE supporting arduino DUE, [1.6.9](http://arduino.cc/en/Main/OldSoftwareReleases) with Due 1.6.8 module from board manager.
|
||||
4. Update variants.cpp arduino file with the one present in src\ArduinoDUE\AdditionalArduinoFile according your IDE version
|
||||
NOTE: You do not need to compile arduino from source these files are in the arduino directory structure (click on preferences.txt in Files/Preferences dialog box).
|
||||
5. Open the project file named repetier.ino located in src\ArduinoDUE\Repetier directory in the arduino IDE.
|
||||
6. Modify the DAVINCI define in Configuration.h file to match your targeted Da Vinci. See below.
|
||||
7. Under the tools menu select the board type as Arduino DUE (Native USB Port) and the proper port you have connected to the printer. NOTE: You can usually find this out by looking at the tools -> port menu both before and after plugging in the printer to your computer's USB.
|
||||
|
@ -58,14 +55,14 @@ If done correctly you will see the arduino sketch compile successfully and outpu
|
|||
For information on upgrading from or reverting to stock FW and other procedures please check [Da Vinci Voltivo forum](http://voltivo.com/forum/davinci).
|
||||
<h4>:warning:There is no known way to revert to stock FW on 1.0A/2.0A/AiO until today.</h4>
|
||||
|
||||
Do not forget to modify the Configuration.h to match your targeted Da Vinci: 1.0, 2.0 SF or 2.0.
|
||||
Do not forget to modify the configuration.h to match your targeted Da Vinci: 1.0, 2.0 SF or 2.0.
|
||||
for basic installation just change :
|
||||
'<code>#define DAVINCI 1 // "1" For DAVINCI 1.0, "2" For DAVINCI 2.0 with 1 FAN, "3" For DAVINCI 2.0 with 2 FANS, 4 For AiO (no scanner)</code>'
|
||||
0 for not Davinci board (like DUE/RADDS)
|
||||
1 for DaVinci 1.0 (1Fan, 1 Extruder)
|
||||
2 for DaVinci 2.0 SF (1Fan, 2 Extruders)
|
||||
3 for DaVinci 2.0 (2Fans, 2 Extruders)
|
||||
4 for DaVinci AiO (no scanner)
|
||||
4 for DaVinci AiO
|
||||
|
||||
Support for 1.0A and 2.0A: need to change <CODE>#define MODEL 0</CODE> to <CODE>#define MODEL 1</CODE>
|
||||
|
||||
|
@ -78,13 +75,18 @@ Or a great video done by Daniel Gonos: https://www.youtube.com/watch?v=rjuCvlnpB
|
|||
|
||||
***
|
||||
##TODO or Questions ?
|
||||
[Check issue list](https://github.com/luc-github/Repetier-Firmware-0.92/issues)
|
||||
[FAQ](https://github.com/luc-github/Repetier-Firmware-0.92/issues?utf8=%E2%9C%93&q=is%3Aclosed+label%3AFAQ+)
|
||||
* [Check issue list](https://github.com/luc-github/Repetier-Firmware-0.92/issues)
|
||||
Do not ask help on repetier github they do not support this FW / printer - please use this [github for issues](https://github.com/luc-github/Repetier-Firmware-0.92/issues)
|
||||
|
||||
* [FAQ](https://github.com/luc-github/Repetier-Firmware-0.92/issues?utf8=%E2%9C%93&q=is%3Aclosed+label%3AFAQ+)
|
||||
|
||||
* [Documentation](https://github.com/luc-github/Repetier-Firmware-0.92/wiki) TBD - feel free to help
|
||||
|
||||
***
|
||||
##Implemented
|
||||
* Standard GCODE commands
|
||||
* Single/Dual extruders support (DaVinci 1.0(a)/2.0(a) and AiO without scanner)
|
||||
* 0.92.10 [Repetier](https://github.com/repetier/Repetier-Firmware) based
|
||||
* Standard GCODE commands
|
||||
* Single/Dual extruders support (DaVinci 1.0/2.0 all generations but AiO)
|
||||
* Single Fan / Dual fans support according printer configuration
|
||||
* Repurpose of second fan usage to be controlled by M106/M107 commands on Da Vinci 2.0
|
||||
* Sound and Lights management, including powersaving function (light can be managed remotely by GCODE)
|
||||
|
@ -104,7 +106,8 @@ Or a great video done by Daniel Gonos: https://www.youtube.com/watch?v=rjuCvlnpB
|
|||
* Several fixes from original FW
|
||||
* Watchdog
|
||||
* Basic Wifi support for module ESP8266 (https://github.com/luc-github/ESP8266/blob/master/README.md#result-of-esp12e-on-davinci)
|
||||
* Customized thermistor tables for bed and extruder(s) as Davinci board do not follow design of others 3D printer boards so standard tables do not work properly [check here](http://voltivo.com/forum/davinci-firmware/438-repetier-91-e3d-v6-extruder#3631)
|
||||
* Customized thermistor tables for bed and extruder(s) as Davinci boards do not follow design of others 3D printer boards so standard tables do not work properly [check here](http://voltivo.com/forum/davinci-firmware/438-repetier-91-e3d-v6-extruder#3631)
|
||||
* Multilanguage at runtime (EN/FR/GE/NL/SW) more to come if get help : check [here](https://github.com/luc-github/Repetier-Firmware-0.92/issues/123)
|
||||
* More to come ....
|
||||
|
||||
***
|
||||
|
@ -119,7 +122,4 @@ If not, you should have "Watchdog feature was not compiled into this version!" i
|
|||
##Current menu (not up to date):
|
||||
Easy: <img src='https://cloud.githubusercontent.com/assets/8822552/4748170/bfa0b7e8-5a69-11e4-80b7-02b9c99fe122.png'>
|
||||
Advanced : <img src='https://cloud.githubusercontent.com/assets/8822552/4748932/bebab9e2-5a7c-11e4-8fea-cdbe3d70820c.png'>
|
||||
***
|
||||
##Donation:
|
||||
Every support is welcome: [<img src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG_global.gif" border="0" alt="PayPal – The safer, easier way to pay online.">](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=VT5LV38N4U3VQ)
|
||||
Especially if need to buy new printer to add FW support.
|
||||
|
||||
|
|
Plik binarny nie jest wyświetlany.
BIN
pinout.xlsx
BIN
pinout.xlsx
Plik binarny nie jest wyświetlany.
|
@ -1,891 +0,0 @@
|
|||
// Copyright (c) 2010, Peter Barrett
|
||||
/*
|
||||
** Permission to use, copy, modify, and/or distribute this software for
|
||||
** any purpose with or without fee is hereby granted, provided that the
|
||||
** above copyright notice and this permission notice appear in all copies.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
||||
** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
||||
** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
** SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "USBAPI.h"
|
||||
#include "Reset.h"
|
||||
#include <stdio.h>
|
||||
|
||||
//#define TRACE_CORE(x) x
|
||||
#define TRACE_CORE(x)
|
||||
|
||||
static const uint32_t EndPoints[] =
|
||||
{
|
||||
EP_TYPE_CONTROL,
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM
|
||||
EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT
|
||||
EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN
|
||||
#endif
|
||||
|
||||
#ifdef HID_ENABLED
|
||||
EP_TYPE_INTERRUPT_IN_HID // HID_ENDPOINT_INT
|
||||
#endif
|
||||
};
|
||||
|
||||
/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */
|
||||
#define TX_RX_LED_PULSE_MS 100
|
||||
volatile uint8_t TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */
|
||||
volatile uint8_t RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */
|
||||
static char isRemoteWakeUpEnabled = 0;
|
||||
static char isEndpointHalt = 0;
|
||||
//==================================================================
|
||||
//==================================================================
|
||||
|
||||
extern const uint16_t STRING_LANGUAGE[];
|
||||
extern const uint8_t STRING_PRODUCT[];
|
||||
extern const uint8_t STRING_MANUFACTURER[];
|
||||
extern const DeviceDescriptor USB_DeviceDescriptor;
|
||||
extern const DeviceDescriptor USB_DeviceDescriptorA;
|
||||
|
||||
const uint16_t STRING_LANGUAGE[2] = {
|
||||
(3<<8) | (2+2),
|
||||
0x0409 // English
|
||||
};
|
||||
|
||||
#ifndef USB_PRODUCT
|
||||
// Use a hardcoded product name if none is provided
|
||||
#if USB_PID == USB_PID_DUE
|
||||
#define USB_PRODUCT "Arduino Due"
|
||||
#else
|
||||
#define USB_PRODUCT "USB IO Board"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const uint8_t STRING_PRODUCT[] = USB_PRODUCT;
|
||||
|
||||
#if USB_VID == 0x2341
|
||||
# if defined(USB_MANUFACTURER)
|
||||
# undef USB_MANUFACTURER
|
||||
# endif
|
||||
# define USB_MANUFACTURER "Arduino LLC"
|
||||
#elif !defined(USB_MANUFACTURER)
|
||||
// Fall through to unknown if no manufacturer name was provided in a macro
|
||||
# define USB_MANUFACTURER "Unknown"
|
||||
#endif
|
||||
|
||||
const uint8_t STRING_MANUFACTURER[12] = USB_MANUFACTURER;
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
#define DEVICE_CLASS 0x02
|
||||
#else
|
||||
#define DEVICE_CLASS 0x00
|
||||
#endif
|
||||
|
||||
// DEVICE DESCRIPTOR
|
||||
const DeviceDescriptor USB_DeviceDescriptor =
|
||||
D_DEVICE(0x00,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1);
|
||||
|
||||
const DeviceDescriptor USB_DeviceDescriptorA =
|
||||
D_DEVICE(DEVICE_CLASS,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1);
|
||||
|
||||
const DeviceDescriptor USB_DeviceQualifier =
|
||||
D_QUALIFIER(0x00,0x00,0x00,64,1);
|
||||
|
||||
//! 7.1.20 Test Mode Support
|
||||
static const unsigned char test_packet_buffer[] = {
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // JKJKJKJK * 9
|
||||
0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, // JJKKJJKK * 8
|
||||
0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE, // JJJJKKKK * 8
|
||||
0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // JJJJJJJKKKKKKK * 8
|
||||
0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD, // JJJJJJJK * 8
|
||||
0xFC,0x7E,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0x7E // {JKKKKKKK * 10}, JK
|
||||
};
|
||||
|
||||
//==================================================================
|
||||
//==================================================================
|
||||
|
||||
volatile uint32_t _usbConfiguration = 0;
|
||||
volatile uint32_t _usbInitialized = 0;
|
||||
uint32_t _usbSetInterface = 0;
|
||||
uint32_t _cdcComposite = 0;
|
||||
|
||||
//==================================================================
|
||||
//==================================================================
|
||||
|
||||
#define USB_RECV_TIMEOUT
|
||||
class LockEP
|
||||
{
|
||||
irqflags_t flags;
|
||||
public:
|
||||
LockEP(uint32_t ep) : flags(cpu_irq_save())
|
||||
{
|
||||
}
|
||||
~LockEP()
|
||||
{
|
||||
cpu_irq_restore(flags);
|
||||
}
|
||||
};
|
||||
|
||||
// Number of bytes, assumes a rx endpoint
|
||||
uint32_t USBD_Available(uint32_t ep)
|
||||
{
|
||||
LockEP lock(ep);
|
||||
return UDD_FifoByteCount(ep & 0xF);
|
||||
}
|
||||
|
||||
// Non Blocking receive
|
||||
// Return number of bytes read
|
||||
uint32_t USBD_Recv(uint32_t ep, void* d, uint32_t len)
|
||||
{
|
||||
if (!_usbConfiguration)
|
||||
return -1;
|
||||
|
||||
LockEP lock(ep);
|
||||
uint32_t n = UDD_FifoByteCount(ep & 0xF);
|
||||
len = min(n,len);
|
||||
n = len;
|
||||
uint8_t* dst = (uint8_t*)d;
|
||||
while (n--)
|
||||
*dst++ = UDD_Recv8(ep & 0xF);
|
||||
if (len && !UDD_FifoByteCount(ep & 0xF)) // release empty buffer
|
||||
UDD_ReleaseRX(ep & 0xF);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
// Recv 1 byte if ready
|
||||
uint32_t USBD_Recv(uint32_t ep)
|
||||
{
|
||||
uint8_t c;
|
||||
if (USBD_Recv(ep & 0xF, &c, 1) != 1)
|
||||
return -1;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
// Space in send EP
|
||||
//uint32_t USBD_SendSpace(uint32_t ep)
|
||||
//{
|
||||
//LockEP lock(ep);
|
||||
//// if (!UDD_ReadWriteAllowed(ep & 0xF))
|
||||
////{
|
||||
////printf("pb "); // UOTGHS->UOTGHS_DEVEPTISR[%d]=0x%X\n\r", ep, UOTGHS->UOTGHS_DEVEPTISR[ep]);
|
||||
////return 0;
|
||||
////}
|
||||
|
||||
//if(ep==0) return 64 - UDD_FifoByteCount(ep & 0xF); // EP0_SIZE jcb
|
||||
//else return 512 - UDD_FifoByteCount(ep & 0xF); // EPX_SIZE jcb
|
||||
//}
|
||||
|
||||
// Blocking Send of data to an endpoint
|
||||
uint32_t USBD_Send(uint32_t ep, const void* d, uint32_t len)
|
||||
{
|
||||
uint32_t n;
|
||||
int r = len;
|
||||
const uint8_t* data = (const uint8_t*)d;
|
||||
|
||||
if (!_usbConfiguration)
|
||||
{
|
||||
TRACE_CORE(printf("pb conf\n\r");)
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (len)
|
||||
{
|
||||
if(ep==0) n = EP0_SIZE;
|
||||
else n = EPX_SIZE;
|
||||
if (n > len)
|
||||
n = len;
|
||||
len -= n;
|
||||
int count=0;
|
||||
while( UOTGHS_DEVEPTISR_TXINI != (UOTGHS->UOTGHS_DEVEPTISR[ep & 0xF] & UOTGHS_DEVEPTISR_TXINI ))
|
||||
{
|
||||
count++;
|
||||
if (count>10000) return len;
|
||||
}
|
||||
UDD_Send(ep & 0xF, data, n);
|
||||
data += n;
|
||||
}
|
||||
//TXLED1; // light the TX LED
|
||||
//TxLEDPulse = TX_RX_LED_PULSE_MS;
|
||||
return r;
|
||||
}
|
||||
|
||||
int _cmark;
|
||||
int _cend;
|
||||
|
||||
void USBD_InitControl(int end)
|
||||
{
|
||||
_cmark = 0;
|
||||
_cend = end;
|
||||
}
|
||||
|
||||
// Clipped by _cmark/_cend
|
||||
int USBD_SendControl(uint8_t flags, const void* d, uint32_t len)
|
||||
{
|
||||
const uint8_t* data = (const uint8_t*)d;
|
||||
uint32_t length = len;
|
||||
uint32_t sent = 0;
|
||||
uint32_t pos = 0;
|
||||
|
||||
TRACE_CORE(printf("=> USBD_SendControl TOTAL len=%lu\r\n", len);)
|
||||
|
||||
if (_cmark < _cend)
|
||||
{
|
||||
while (len > 0)
|
||||
{
|
||||
sent = UDD_Send(EP0, data + pos, len);
|
||||
TRACE_CORE(printf("=> USBD_SendControl sent=%lu\r\n", sent);)
|
||||
pos += sent;
|
||||
len -= sent;
|
||||
}
|
||||
}
|
||||
|
||||
_cmark += length;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
// Send a USB descriptor string. The string is stored as a
|
||||
// plain ASCII string but is sent out as UTF-16 with the
|
||||
// correct 2-byte prefix
|
||||
static bool USB_SendStringDescriptor(const uint8_t *string, int wLength) {
|
||||
uint16_t buff[64];
|
||||
int l = 1;
|
||||
wLength-=2;
|
||||
while (*string && wLength>0) {
|
||||
buff[l++] = (uint8_t)(*string++);
|
||||
wLength-=2;
|
||||
}
|
||||
buff[0] = (3<<8) | (l*2);
|
||||
return USBD_SendControl(0, (uint8_t*)buff, l*2);
|
||||
}
|
||||
|
||||
// Does not timeout or cross fifo boundaries
|
||||
// Will only work for transfers <= 64 bytes
|
||||
// TODO
|
||||
int USBD_RecvControl(void* d, uint32_t len)
|
||||
{
|
||||
UDD_WaitOUT();
|
||||
UDD_Recv(EP0, (uint8_t*)d, len);
|
||||
UDD_ClearOUT();
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
// Handle CLASS_INTERFACE requests
|
||||
bool USBD_ClassInterfaceRequest(Setup& setup)
|
||||
{
|
||||
uint8_t i = setup.wIndex;
|
||||
|
||||
TRACE_CORE(printf("=> USBD_ClassInterfaceRequest\r\n");)
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
if (CDC_ACM_INTERFACE == i)
|
||||
{
|
||||
return CDC_Setup(setup);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HID_ENABLED
|
||||
if (HID_INTERFACE == i)
|
||||
{
|
||||
return HID_Setup(setup);
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int USBD_SendInterfaces(void)
|
||||
{
|
||||
int total = 0;
|
||||
uint8_t interfaces = 0;
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
total = CDC_GetInterface(&interfaces);
|
||||
#endif
|
||||
|
||||
#ifdef HID_ENABLED
|
||||
total += HID_GetInterface(&interfaces);
|
||||
#endif
|
||||
|
||||
total = total; // Get rid of compiler warning
|
||||
TRACE_CORE(printf("=> USBD_SendInterfaces, total=%d interfaces=%d\r\n", total, interfaces);)
|
||||
return interfaces;
|
||||
}
|
||||
|
||||
int USBD_SendOtherInterfaces(void)
|
||||
{
|
||||
int total = 0;
|
||||
uint8_t interfaces = 0;
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
total = CDC_GetOtherInterface(&interfaces);
|
||||
#endif
|
||||
|
||||
#ifdef HID_ENABLED
|
||||
total += HID_GetInterface(&interfaces);
|
||||
#endif
|
||||
|
||||
total = total; // Get rid of compiler warning
|
||||
TRACE_CORE(printf("=> USBD_SendInterfaces, total=%d interfaces=%d\r\n", total, interfaces);)
|
||||
return interfaces;
|
||||
}
|
||||
|
||||
// Construct a dynamic configuration descriptor
|
||||
// This really needs dynamic endpoint allocation etc
|
||||
// TODO
|
||||
static bool USBD_SendConfiguration(int maxlen)
|
||||
{
|
||||
// Count and measure interfaces
|
||||
USBD_InitControl(0);
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration _cmark1=%d\r\n", _cmark);)
|
||||
int interfaces = USBD_SendInterfaces();
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration _cmark2=%d\r\n", _cmark);)
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration sizeof=%d\r\n", sizeof(ConfigDescriptor));)
|
||||
|
||||
_Pragma("pack(1)")
|
||||
ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces);
|
||||
_Pragma("pack()")
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration clen=%d\r\n", config.clen);)
|
||||
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration maxlen=%d\r\n", maxlen);)
|
||||
|
||||
// Now send them
|
||||
USBD_InitControl(maxlen);
|
||||
USBD_SendControl(0,&config,sizeof(ConfigDescriptor));
|
||||
USBD_SendInterfaces();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool USBD_SendOtherConfiguration(int maxlen)
|
||||
{
|
||||
// Count and measure interfaces
|
||||
USBD_InitControl(0);
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration _cmark1=%d\r\n", _cmark);)
|
||||
int interfaces = USBD_SendOtherInterfaces();
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration _cmark2=%d\r\n", _cmark);)
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration sizeof=%d\r\n", sizeof(ConfigDescriptor));)
|
||||
|
||||
_Pragma("pack(1)")
|
||||
ConfigDescriptor config = D_OTHERCONFIG(_cmark + sizeof(ConfigDescriptor),interfaces);
|
||||
_Pragma("pack()")
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration clen=%d\r\n", config.clen);)
|
||||
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration maxlen=%d\r\n", maxlen);)
|
||||
|
||||
// Now send them
|
||||
USBD_InitControl(maxlen);
|
||||
USBD_SendControl(0,&config,sizeof(ConfigDescriptor));
|
||||
USBD_SendOtherInterfaces();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool USBD_SendDescriptor(Setup& setup)
|
||||
{
|
||||
uint8_t t = setup.wValueH;
|
||||
uint8_t desc_length = 0;
|
||||
const uint8_t* desc_addr = 0;
|
||||
|
||||
if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t)
|
||||
{
|
||||
TRACE_CORE(printf("=> USBD_SendDescriptor : USB_CONFIGURATION_DESCRIPTOR_TYPE length=%d\r\n", setup.wLength);)
|
||||
return USBD_SendConfiguration(setup.wLength);
|
||||
}
|
||||
|
||||
USBD_InitControl(setup.wLength);
|
||||
#ifdef HID_ENABLED
|
||||
if (HID_REPORT_DESCRIPTOR_TYPE == t)
|
||||
{
|
||||
TRACE_CORE(puts("=> USBD_SendDescriptor : HID_REPORT_DESCRIPTOR_TYPE\r\n");)
|
||||
return HID_GetDescriptor(t);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (USB_DEVICE_DESCRIPTOR_TYPE == t)
|
||||
{
|
||||
TRACE_CORE(puts("=> USBD_SendDescriptor : USB_DEVICE_DESCRIPTOR_TYPE\r\n");)
|
||||
if (setup.wLength == 8)
|
||||
{
|
||||
_cdcComposite = 1;
|
||||
}
|
||||
desc_addr = _cdcComposite ? (const uint8_t*)&USB_DeviceDescriptorA : (const uint8_t*)&USB_DeviceDescriptor;
|
||||
if( *desc_addr > setup.wLength ) {
|
||||
desc_length = setup.wLength;
|
||||
}
|
||||
}
|
||||
else if (USB_STRING_DESCRIPTOR_TYPE == t)
|
||||
{
|
||||
TRACE_CORE(puts("=> USBD_SendDescriptor : USB_STRING_DESCRIPTOR_TYPE\r\n");)
|
||||
if (setup.wValueL == 0) {
|
||||
desc_addr = (const uint8_t*)&STRING_LANGUAGE;
|
||||
}
|
||||
else if (setup.wValueL == IPRODUCT) {
|
||||
return USB_SendStringDescriptor(STRING_PRODUCT, setup.wLength);
|
||||
}
|
||||
else if (setup.wValueL == IMANUFACTURER) {
|
||||
return USB_SendStringDescriptor(STRING_MANUFACTURER, setup.wLength);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
if( *desc_addr > setup.wLength ) {
|
||||
desc_length = setup.wLength;
|
||||
}
|
||||
}
|
||||
else if (USB_DEVICE_QUALIFIER == t)
|
||||
{
|
||||
// Device qualifier descriptor requested
|
||||
desc_addr = (const uint8_t*)&USB_DeviceQualifier;
|
||||
if( *desc_addr > setup.wLength ) {
|
||||
desc_length = setup.wLength;
|
||||
}
|
||||
}
|
||||
else if (USB_OTHER_SPEED_CONFIGURATION == t)
|
||||
{
|
||||
// Other configuration descriptor requested
|
||||
return USBD_SendOtherConfiguration(setup.wLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("Device ERROR");
|
||||
}
|
||||
|
||||
if (desc_addr == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (desc_length == 0)
|
||||
{
|
||||
desc_length = *desc_addr;
|
||||
}
|
||||
|
||||
TRACE_CORE(printf("=> USBD_SendDescriptor : desc_addr=%p desc_length=%d\r\n", desc_addr, desc_length);)
|
||||
USBD_SendControl(0, desc_addr, desc_length);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void USB_SendZlp( void )
|
||||
{
|
||||
while( UOTGHS_DEVEPTISR_TXINI != (UOTGHS->UOTGHS_DEVEPTISR[0] & UOTGHS_DEVEPTISR_TXINI ) )
|
||||
{
|
||||
if((UOTGHS->UOTGHS_DEVISR & UOTGHS_DEVISR_SUSP) == UOTGHS_DEVISR_SUSP)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
UOTGHS->UOTGHS_DEVEPTICR[0] = UOTGHS_DEVEPTICR_TXINIC;
|
||||
}
|
||||
|
||||
|
||||
static void Test_Mode_Support( uint8_t wIndex )
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(2);
|
||||
|
||||
switch( wIndex )
|
||||
{
|
||||
case 4:
|
||||
//Test mode Test_Packet:
|
||||
//Upon command, a port must repetitively transmit the following test packet until
|
||||
//the exit action is taken. This enables the testing of rise and fall times, eye
|
||||
//patterns, jitter, and any other dynamic waveform specifications.
|
||||
//The test packet is made up by concatenating the following strings.
|
||||
//(Note: For J/K NRZI data, and for NRZ data, the bit on the left is the first one
|
||||
//transmitted. "S" indicates that a bit stuff occurs, which inserts an "extra" NRZI data bit.
|
||||
//"* N" is used to indicate N occurrences of a string of bits or symbols.)
|
||||
//A port in Test_Packet mode must send this packet repetitively. The inter-packet timing
|
||||
//must be no less than the minimum allowable inter-packet gap as defined in Section 7.1.18 and
|
||||
//no greater than 125 us.
|
||||
|
||||
// Send ZLP
|
||||
USB_SendZlp();
|
||||
|
||||
UOTGHS->UOTGHS_DEVDMA[0].UOTGHS_DEVDMACONTROL = 0; // raz
|
||||
UOTGHS->UOTGHS_DEVDMA[1].UOTGHS_DEVDMACONTROL = 0; // raz
|
||||
|
||||
// Configure endpoint 2, 64 bytes, direction IN, type BULK, 1 bank
|
||||
UOTGHS->UOTGHS_DEVEPTCFG[2] = UOTGHS_DEVEPTCFG_EPSIZE_64_BYTE
|
||||
| UOTGHS_DEVEPTCFG_EPDIR_IN
|
||||
| UOTGHS_DEVEPTCFG_EPTYPE_BLK
|
||||
| UOTGHS_DEVEPTCFG_EPBK_1_BANK;
|
||||
// Check if the configuration is ok
|
||||
UOTGHS->UOTGHS_DEVEPTCFG[2] |= UOTGHS_DEVEPTCFG_ALLOC;
|
||||
while((UOTGHS->UOTGHS_DEVEPTISR[2]&UOTGHS_DEVEPTISR_CFGOK)==0) {}
|
||||
UOTGHS->UOTGHS_DEVEPT |= UOTGHS_DEVEPT_EPEN2;
|
||||
// Write FIFO
|
||||
for( i=0; i<sizeof(test_packet_buffer); i++)
|
||||
{
|
||||
ptr_dest[i] = test_packet_buffer[i];;
|
||||
}
|
||||
// Tst PACKET
|
||||
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_TSTPCKT;
|
||||
// Send packet
|
||||
UOTGHS->UOTGHS_DEVEPTICR[2] = UOTGHS_DEVEPTICR_TXINIC;
|
||||
UOTGHS->UOTGHS_DEVEPTIDR[2] = UOTGHS_DEVEPTIDR_FIFOCONC;
|
||||
for(;;);
|
||||
// break;
|
||||
|
||||
case 1:
|
||||
//Test mode Test_J:
|
||||
//Upon command, a port's transceiver must enter the high-speed J state and remain in that
|
||||
//state until the exit action is taken. This enables the testing of the high output drive
|
||||
//level on the D+ line.
|
||||
// Send a ZLP
|
||||
USB_SendZlp();
|
||||
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_TSTJ;
|
||||
for(;;);
|
||||
// break;
|
||||
|
||||
case 2:
|
||||
//Test mode Test_K:
|
||||
//Upon command, a port's transceiver must enter the high-speed K state and remain in
|
||||
//that state until the exit action is taken. This enables the testing of the high output drive
|
||||
//level on the D- line.
|
||||
// Send a ZLP
|
||||
USB_SendZlp();
|
||||
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_TSTK;
|
||||
for(;;);
|
||||
// break;
|
||||
|
||||
case 3:
|
||||
//Test mode Test_SE0_NAK:
|
||||
//Upon command, a port's transceiver must enter the high-speed receive mode
|
||||
//and remain in that mode until the exit action is taken. This enables the testing
|
||||
//of output impedance, low level output voltage, and loading characteristics.
|
||||
//In addition, while in this mode, upstream facing ports (and only upstream facing ports)
|
||||
//must respond to any IN token packet with a NAK handshake (only if the packet CRC is
|
||||
//determined to be correct) within the normal allowed device response time. This enables testing of
|
||||
//the device squelch level circuitry and, additionally, provides a general purpose stimulus/response
|
||||
//test for basic functional testing.
|
||||
|
||||
// Send a ZLP
|
||||
USB_SendZlp();
|
||||
UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_SUSPEC
|
||||
| UOTGHS_DEVIDR_MSOFEC
|
||||
| UOTGHS_DEVIDR_SOFEC
|
||||
| UOTGHS_DEVIDR_EORSTEC
|
||||
| UOTGHS_DEVIDR_WAKEUPEC
|
||||
| UOTGHS_DEVIDR_EORSMEC
|
||||
| UOTGHS_DEVIDR_UPRSMEC
|
||||
| UOTGHS_DEVIDR_PEP_0
|
||||
| UOTGHS_DEVIDR_PEP_1
|
||||
| UOTGHS_DEVIDR_PEP_2
|
||||
| UOTGHS_DEVIDR_PEP_3
|
||||
| UOTGHS_DEVIDR_PEP_4
|
||||
| UOTGHS_DEVIDR_PEP_5
|
||||
| UOTGHS_DEVIDR_PEP_6
|
||||
| UOTGHS_DEVIDR_DMA_1
|
||||
| UOTGHS_DEVIDR_DMA_2
|
||||
| UOTGHS_DEVIDR_DMA_3
|
||||
| UOTGHS_DEVIDR_DMA_4
|
||||
| UOTGHS_DEVIDR_DMA_5
|
||||
| UOTGHS_DEVIDR_DMA_6;
|
||||
for(;;);
|
||||
// break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//unsigned int iii=0;
|
||||
// Endpoint 0 interrupt
|
||||
static void USB_ISR(void)
|
||||
{
|
||||
// printf("ISR=0x%X\n\r", UOTGHS->UOTGHS_DEVISR); // jcb
|
||||
// if( iii++ > 1500 ) while(1); // jcb
|
||||
// End of bus reset
|
||||
if (Is_udd_reset())
|
||||
{
|
||||
TRACE_CORE(printf(">>> End of Reset\r\n");)
|
||||
|
||||
// Reset USB address to 0
|
||||
udd_configure_address(0);
|
||||
udd_enable_address();
|
||||
|
||||
// Configure EP 0
|
||||
UDD_InitEP(0, EP_TYPE_CONTROL);
|
||||
udd_enable_setup_received_interrupt(0);
|
||||
udd_enable_endpoint_interrupt(0);
|
||||
|
||||
_usbConfiguration = 0;
|
||||
udd_ack_reset();
|
||||
}
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
if (Is_udd_endpoint_interrupt(CDC_RX))
|
||||
{
|
||||
udd_ack_out_received(CDC_RX);
|
||||
|
||||
// Handle received bytes
|
||||
if (USBD_Available(CDC_RX))
|
||||
SerialUSB.accept();
|
||||
}
|
||||
|
||||
if (Is_udd_sof())
|
||||
{
|
||||
udd_ack_sof();
|
||||
// USBD_Flush(CDC_TX); // jcb
|
||||
}
|
||||
#endif
|
||||
|
||||
// EP 0 Interrupt
|
||||
if (Is_udd_endpoint_interrupt(0) )
|
||||
{
|
||||
if (!UDD_ReceivedSetupInt())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Setup setup;
|
||||
UDD_Recv(EP0, (uint8_t*)&setup, 8);
|
||||
UDD_ClearSetupInt();
|
||||
|
||||
uint8_t requestType = setup.bmRequestType;
|
||||
if (requestType & REQUEST_DEVICETOHOST)
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: IN Request\r\n");)
|
||||
UDD_WaitIN();
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: OUT Request\r\n");)
|
||||
UDD_ClearIN();
|
||||
}
|
||||
|
||||
bool ok = true;
|
||||
if (REQUEST_STANDARD == (requestType & REQUEST_TYPE))
|
||||
{
|
||||
// Standard Requests
|
||||
uint8_t r = setup.bRequest;
|
||||
if (GET_STATUS == r)
|
||||
{
|
||||
if( setup.bmRequestType == 0 ) // device
|
||||
{
|
||||
// Send the device status
|
||||
TRACE_CORE(puts(">>> EP0 Int: GET_STATUS\r\n");)
|
||||
// Check current configuration for power mode (if device is configured)
|
||||
// TODO
|
||||
// Check if remote wake-up is enabled
|
||||
// TODO
|
||||
UDD_Send8(EP0, 0); // TODO
|
||||
UDD_Send8(EP0, 0);
|
||||
}
|
||||
// if( setup.bmRequestType == 2 ) // Endpoint:
|
||||
else
|
||||
{
|
||||
// Send the endpoint status
|
||||
// Check if the endpoint if currently halted
|
||||
if( isEndpointHalt == 1 )
|
||||
UDD_Send8(EP0, 1); // TODO
|
||||
else
|
||||
UDD_Send8(EP0, 0); // TODO
|
||||
UDD_Send8(EP0, 0);
|
||||
}
|
||||
}
|
||||
else if (CLEAR_FEATURE == r)
|
||||
{
|
||||
// Check which is the selected feature
|
||||
if( setup.wValueL == 1) // DEVICEREMOTEWAKEUP
|
||||
{
|
||||
// Enable remote wake-up and send a ZLP
|
||||
if( isRemoteWakeUpEnabled == 1 )
|
||||
UDD_Send8(EP0, 1);
|
||||
else
|
||||
UDD_Send8(EP0, 0);
|
||||
UDD_Send8(EP0, 0);
|
||||
}
|
||||
else // if( setup.wValueL == 0) // ENDPOINTHALT
|
||||
{
|
||||
isEndpointHalt = 0; // TODO
|
||||
UDD_Send8(EP0, 0);
|
||||
UDD_Send8(EP0, 0);
|
||||
}
|
||||
|
||||
}
|
||||
else if (SET_FEATURE == r)
|
||||
{
|
||||
// Check which is the selected feature
|
||||
if( setup.wValueL == 1) // DEVICEREMOTEWAKEUP
|
||||
{
|
||||
// Enable remote wake-up and send a ZLP
|
||||
isRemoteWakeUpEnabled = 1;
|
||||
UDD_Send8(EP0, 0);
|
||||
}
|
||||
if( setup.wValueL == 0) // ENDPOINTHALT
|
||||
{
|
||||
// Halt endpoint
|
||||
isEndpointHalt = 1;
|
||||
//USBD_Halt(USBGenericRequest_GetEndpointNumber(pRequest));
|
||||
UDD_Send8(EP0, 0);
|
||||
}
|
||||
if( setup.wValueL == 2) // TEST_MODE
|
||||
{
|
||||
// 7.1.20 Test Mode Support, 9.4.9 SetFeature
|
||||
if( (setup.bmRequestType == 0 /*USBGenericRequest_DEVICE*/) &&
|
||||
((setup.wIndex & 0x000F) == 0) )
|
||||
{
|
||||
// the lower byte of wIndex must be zero
|
||||
// the most significant byte of wIndex is used to specify the specific test mode
|
||||
|
||||
UOTGHS->UOTGHS_DEVIDR &= ~UOTGHS_DEVIDR_SUSPEC;
|
||||
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_SPDCONF_HIGH_SPEED; // remove suspend ?
|
||||
|
||||
Test_Mode_Support( (setup.wIndex & 0xFF00)>>8 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (SET_ADDRESS == r)
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: SET_ADDRESS\r\n");)
|
||||
UDD_WaitIN();
|
||||
UDD_SetAddress(setup.wValueL);
|
||||
}
|
||||
else if (GET_DESCRIPTOR == r)
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: GET_DESCRIPTOR\r\n");)
|
||||
ok = USBD_SendDescriptor(setup);
|
||||
}
|
||||
else if (SET_DESCRIPTOR == r)
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: SET_DESCRIPTOR\r\n");)
|
||||
ok = false;
|
||||
}
|
||||
else if (GET_CONFIGURATION == r)
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: GET_CONFIGURATION\r\n");)
|
||||
UDD_Send8(EP0, _usbConfiguration);
|
||||
}
|
||||
else if (SET_CONFIGURATION == r)
|
||||
{
|
||||
if (REQUEST_DEVICE == (requestType & REQUEST_RECIPIENT))
|
||||
{
|
||||
TRACE_CORE(printf(">>> EP0 Int: SET_CONFIGURATION REQUEST_DEVICE %d\r\n", setup.wValueL);)
|
||||
|
||||
UDD_InitEndpoints(EndPoints, (sizeof(EndPoints) / sizeof(EndPoints[0])));
|
||||
_usbConfiguration = setup.wValueL;
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
// Enable interrupt for CDC reception from host (OUT packet)
|
||||
udd_enable_out_received_interrupt(CDC_RX);
|
||||
udd_enable_endpoint_interrupt(CDC_RX);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: SET_CONFIGURATION failed!\r\n");)
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
else if (GET_INTERFACE == r)
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: GET_INTERFACE\r\n");)
|
||||
UDD_Send8(EP0, _usbSetInterface);
|
||||
}
|
||||
else if (SET_INTERFACE == r)
|
||||
{
|
||||
_usbSetInterface = setup.wValueL;
|
||||
TRACE_CORE(puts(">>> EP0 Int: SET_INTERFACE\r\n");)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: ClassInterfaceRequest\r\n");)
|
||||
|
||||
UDD_WaitIN(); // Workaround: need tempo here, else CDC serial won't open correctly
|
||||
|
||||
USBD_InitControl(setup.wLength); // Max length of transfer
|
||||
ok = USBD_ClassInterfaceRequest(setup);
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: Send packet\r\n");)
|
||||
UDD_ClearIN();
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: Stall\r\n");)
|
||||
UDD_Stall();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void USBD_Flush(uint32_t ep)
|
||||
{
|
||||
if (UDD_FifoByteCount(ep))
|
||||
UDD_ReleaseTX(ep);
|
||||
}
|
||||
|
||||
// VBUS or counting frames
|
||||
// Any frame counting?
|
||||
uint32_t USBD_Connected(void)
|
||||
{
|
||||
uint8_t f = UDD_GetFrameNumber();
|
||||
|
||||
delay(3);
|
||||
|
||||
return f != UDD_GetFrameNumber();
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//=======================================================================
|
||||
|
||||
USBDevice_ USBDevice;
|
||||
|
||||
USBDevice_::USBDevice_()
|
||||
{
|
||||
UDD_SetStack(&USB_ISR);
|
||||
|
||||
if (UDD_Init() == 0UL)
|
||||
{
|
||||
_usbInitialized=1UL;
|
||||
}
|
||||
}
|
||||
|
||||
bool USBDevice_::attach(void)
|
||||
{
|
||||
if (_usbInitialized != 0UL)
|
||||
{
|
||||
UDD_Attach();
|
||||
_usbConfiguration = 0;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool USBDevice_::detach(void)
|
||||
{
|
||||
if (_usbInitialized != 0UL)
|
||||
{
|
||||
UDD_Detach();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for interrupts
|
||||
// TODO: VBUS detection
|
||||
bool USBDevice_::configured()
|
||||
{
|
||||
return _usbConfiguration;
|
||||
}
|
||||
|
||||
void USBDevice_::poll()
|
||||
{
|
||||
}
|
|
@ -1,492 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2011 Arduino. 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
|
||||
*/
|
||||
|
||||
#include "variant.h"
|
||||
|
||||
/*
|
||||
* DUE Board pin | PORT | Label
|
||||
* ----------------+--------+-------
|
||||
* 0 | PA8 | "RX0"
|
||||
* 1 | PA9 | "TX0"
|
||||
* 2 TIOA0 | PB25 |
|
||||
* 3 TIOA7 | PC28 |
|
||||
* 4 NPCS1 | PA29 |
|
||||
* TIOB6 | PC26 |
|
||||
* 5 TIOA6 | PC25 |
|
||||
* 6 PWML7 | PC24 |
|
||||
* 7 PWML6 | PC23 |
|
||||
* 8 PWML5 | PC22 |
|
||||
* 9 PWML4 | PC21 |
|
||||
* 10 NPCS0 | PA28 |
|
||||
* TIOB7 | PC29 |
|
||||
* 11 TIOA8 | PD7 |
|
||||
* 12 TIOB8 | PD8 |
|
||||
* 13 TIOB0 | PB27 | LED AMBER "L"
|
||||
* 14 TXD3 | PD4 | "TX3"
|
||||
* 15 RXD3 | PD5 | "RX3"
|
||||
* 16 TXD1 | PA13 | "TX2"
|
||||
* 17 RXD1 | PA12 | "RX2"
|
||||
* 18 TXD0 | PA11 | "TX1"
|
||||
* 19 RXD0 | PA10 | "RX1"
|
||||
* 20 | PB12 | "SDA"
|
||||
* 21 | PB13 | "SCL"
|
||||
* 22 | PB26 |
|
||||
* 23 | PA14 |
|
||||
* 24 | PA15 |
|
||||
* 25 | PD0 |
|
||||
* 26 | PD1 |
|
||||
* 27 | PD2 |
|
||||
* 28 | PD3 |
|
||||
* 29 | PD6 |
|
||||
* 30 | PD9 |
|
||||
* 31 | PA7 |
|
||||
* 32 | PD10 |
|
||||
* 33 | PC1 |
|
||||
* 34 | PC2 |
|
||||
* 35 | PC3 |
|
||||
* 36 | PC4 |
|
||||
* 37 | PC5 |
|
||||
* 38 | PC6 |
|
||||
* 39 | PC7 |
|
||||
* 40 | PC8 |
|
||||
* 41 | PC9 |
|
||||
* 42 | PA19 |
|
||||
* 43 | PA20 |
|
||||
* 44 | PC19 |
|
||||
* 45 | PC18 |
|
||||
* 46 | PC17 |
|
||||
* 47 | PC16 |
|
||||
* 48 | PC15 |
|
||||
* 49 | PC14 |
|
||||
* 50 | PC13 |
|
||||
* 51 | PC12 |
|
||||
* 52 NPCS2 | PB21 |
|
||||
* 53 | PB14 |
|
||||
* 54 | PA16 | "A0"
|
||||
* 55 | PA24 | "A1"
|
||||
* 56 | PA23 | "A2"
|
||||
* 57 | PA22 | "A3"
|
||||
* 58 TIOB2 | PA6 | "A4"
|
||||
* 69 | PA4 | "A5"
|
||||
* 60 TIOB1 | PA3 | "A6"
|
||||
* 61 TIOA1 | PA2 | "A7"
|
||||
* 62 | PB17 | "A8"
|
||||
* 63 | PB18 | "A9"
|
||||
* 64 | PB19 | "A10"
|
||||
* 65 | PB20 | "A11"
|
||||
* 66 | PB15 | "DAC0"
|
||||
* 67 | PB16 | "DAC1"
|
||||
* 68 | PA1 | "CANRX"
|
||||
* 69 | PA0 | "CANTX"
|
||||
* 70 | PA17 | "SDA1"
|
||||
* 71 | PA18 | "SCL1"
|
||||
* 72 | PC30 | LED AMBER "RX"
|
||||
* 73 | PA21 | LED AMBER "TX"
|
||||
* 74 MISO | PA25 |
|
||||
* 75 MOSI | PA26 |
|
||||
* 76 SCLK | PA27 |
|
||||
* 77 NPCS0 | PA28 |
|
||||
* 78 NPCS3 | PB23 | unconnected!
|
||||
*
|
||||
* USB pin | PORT
|
||||
* ----------------+--------
|
||||
* ID | PB11
|
||||
* VBOF | PB10
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Pins descriptions
|
||||
*/
|
||||
extern const PinDescription g_APinDescription[]=
|
||||
{
|
||||
// 0 .. 53 - Digital pins
|
||||
// ----------------------
|
||||
// 0/1 - UART (Serial)
|
||||
{ PIOA, PIO_PA8A_URXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // URXD
|
||||
{ PIOA, PIO_PA9A_UTXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // UTXD
|
||||
|
||||
// 2
|
||||
{ PIOB, PIO_PB25B_TIOA0, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC0_CHA0 }, // TIOA0
|
||||
{ PIOC, PIO_PC28B_TIOA7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA7 }, // TIOA7
|
||||
{ PIOC, PIO_PC26B_TIOB6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB6 }, // TIOB6
|
||||
|
||||
// 5
|
||||
{ PIOC, PIO_PC25B_TIOA6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA6 }, // TIOA6
|
||||
{ PIOC, PIO_PC24B_PWML7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH7, NOT_ON_TIMER }, // PWML7
|
||||
{ PIOC, PIO_PC23B_PWML6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH6, NOT_ON_TIMER }, // PWML6
|
||||
{ PIOC, PIO_PC22B_PWML5, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH5, NOT_ON_TIMER }, // PWML5
|
||||
{ PIOC, PIO_PC21B_PWML4, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH4, NOT_ON_TIMER }, // PWML4
|
||||
// 10
|
||||
{ PIOC, PIO_PC29B_TIOB7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB7 }, // TIOB7
|
||||
{ PIOD, PIO_PD7B_TIOA8, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA8 }, // TIOA8
|
||||
{ PIOD, PIO_PD8B_TIOB8, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB8 }, // TIOB8
|
||||
|
||||
// 13 - AMBER LED
|
||||
{ PIOB, PIO_PB27B_TIOB0, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC0_CHB0 }, // TIOB0
|
||||
|
||||
// 14/15 - USART3 (Serial3)
|
||||
{ PIOD, PIO_PD4B_TXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD3
|
||||
{ PIOD, PIO_PD5B_RXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD3
|
||||
|
||||
// 16/17 - USART1 (Serial2)
|
||||
{ PIOA, PIO_PA13A_TXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD1
|
||||
{ PIOA, PIO_PA12A_RXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD1
|
||||
|
||||
// 18/19 - USART0 (Serial1)
|
||||
{ PIOA, PIO_PA11A_TXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD0
|
||||
{ PIOA, PIO_PA10A_RXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD0
|
||||
|
||||
// 20/21 - TWI1
|
||||
{ PIOB, PIO_PB12A_TWD1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWD1 - SDA0
|
||||
{ PIOB, PIO_PB13A_TWCK1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWCK1 - SCL0
|
||||
|
||||
// 22
|
||||
{ PIOB, PIO_PB26, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 22
|
||||
{ PIOA, PIO_PA14, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 23
|
||||
{ PIOA, PIO_PA15, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 24
|
||||
{ PIOD, PIO_PD0, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 25
|
||||
|
||||
// 26
|
||||
{ PIOD, PIO_PD1, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 26
|
||||
{ PIOD, PIO_PD2, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 27
|
||||
{ PIOD, PIO_PD3, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 28
|
||||
{ PIOD, PIO_PD6, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 29
|
||||
|
||||
// 30
|
||||
{ PIOD, PIO_PD9, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 30
|
||||
{ PIOA, PIO_PA7, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 31
|
||||
{ PIOD, PIO_PD10, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 32
|
||||
{ PIOC, PIO_PC1, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 33
|
||||
|
||||
// 34
|
||||
{ PIOC, PIO_PC2, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 34
|
||||
{ PIOC, PIO_PC3, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 35
|
||||
{ PIOC, PIO_PC4, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 36
|
||||
{ PIOC, PIO_PC5, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 37
|
||||
|
||||
// 38
|
||||
{ PIOC, PIO_PC6, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 38
|
||||
{ PIOC, PIO_PC7, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 39
|
||||
{ PIOC, PIO_PC8, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 40
|
||||
{ PIOC, PIO_PC9, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 41
|
||||
|
||||
// 42
|
||||
{ PIOA, PIO_PA19, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 42
|
||||
{ PIOA, PIO_PA20, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 43
|
||||
{ PIOC, PIO_PC19, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 44
|
||||
{ PIOC, PIO_PC18, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 45
|
||||
|
||||
// 46
|
||||
{ PIOC, PIO_PC17, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 46
|
||||
{ PIOC, PIO_PC16, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 47
|
||||
{ PIOC, PIO_PC15, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 48
|
||||
{ PIOC, PIO_PC14, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 49
|
||||
|
||||
// 50
|
||||
{ PIOC, PIO_PC13, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 50
|
||||
{ PIOC, PIO_PC12, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 51
|
||||
{ PIOB, PIO_PB21, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 52
|
||||
{ PIOB, PIO_PB14, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 53
|
||||
|
||||
|
||||
// 54 .. 65 - Analog pins
|
||||
// ----------------------
|
||||
{ PIOA, PIO_PA16X1_AD7, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC0, ADC7, NOT_ON_PWM, NOT_ON_TIMER }, // AD0
|
||||
{ PIOA, PIO_PA24X1_AD6, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC1, ADC6, NOT_ON_PWM, NOT_ON_TIMER }, // AD1
|
||||
{ PIOA, PIO_PA23X1_AD5, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC2, ADC5, NOT_ON_PWM, NOT_ON_TIMER }, // AD2
|
||||
{ PIOA, PIO_PA22X1_AD4, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC3, ADC4, NOT_ON_PWM, NOT_ON_TIMER }, // AD3
|
||||
// 58
|
||||
{ PIOA, PIO_PA6X1_AD3, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC4, ADC3, NOT_ON_PWM, TC0_CHB2 }, // AD4
|
||||
{ PIOA, PIO_PA4X1_AD2, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC5, ADC2, NOT_ON_PWM, NOT_ON_TIMER }, // AD5
|
||||
{ PIOA, PIO_PA3X1_AD1, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC6, ADC1, NOT_ON_PWM, TC0_CHB1 }, // AD6
|
||||
{ PIOA, PIO_PA2X1_AD0, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC7, ADC0, NOT_ON_PWM, TC0_CHA1 }, // AD7
|
||||
// 62
|
||||
{ PIOB, PIO_PB17X1_AD10, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC8, ADC10, NOT_ON_PWM, NOT_ON_TIMER }, // AD8
|
||||
{ PIOB, PIO_PB18X1_AD11, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC9, ADC11, NOT_ON_PWM, NOT_ON_TIMER }, // AD9
|
||||
{ PIOB, PIO_PB19X1_AD12, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC10, ADC12, NOT_ON_PWM, NOT_ON_TIMER }, // AD10
|
||||
{ PIOB, PIO_PB20X1_AD13, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC11, ADC13, NOT_ON_PWM, NOT_ON_TIMER }, // AD11
|
||||
|
||||
// 66/67 - DAC0/DAC1
|
||||
{ PIOB, PIO_PB15X1_DAC0, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC12, DA0, NOT_ON_PWM, NOT_ON_TIMER }, // DAC0
|
||||
{ PIOB, PIO_PB16X1_DAC1, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC13, DA1, NOT_ON_PWM, NOT_ON_TIMER }, // DAC1
|
||||
|
||||
// 68/69 - CANRX0/CANTX0
|
||||
{ PIOA, PIO_PA1A_CANRX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, ADC14, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANRX
|
||||
{ PIOA, PIO_PA0A_CANTX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, ADC15, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANTX
|
||||
|
||||
// 70/71 - TWI0
|
||||
{ PIOA, PIO_PA17A_TWD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWD0 - SDA1
|
||||
{ PIOA, PIO_PA18A_TWCK0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWCK0 - SCL1
|
||||
|
||||
// 72/73 - LEDs
|
||||
{ PIOC, PIO_PC30, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // LED AMBER RXL
|
||||
{ PIOA, PIO_PA21, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // LED AMBER TXL
|
||||
|
||||
// 74/75/76 - SPI
|
||||
{ PIOA, PIO_PA25A_SPI0_MISO,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // MISO
|
||||
{ PIOA, PIO_PA26A_SPI0_MOSI,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // MOSI
|
||||
{ PIOA, PIO_PA27A_SPI0_SPCK,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // SPCK
|
||||
|
||||
// 77 - SPI CS0
|
||||
{ PIOA, PIO_PA28A_SPI0_NPCS0,ID_PIOA,PIO_PERIPH_A,PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS0
|
||||
|
||||
// 78 - SPI CS3 (unconnected)
|
||||
{ PIOB, PIO_PB23B_SPI0_NPCS3,ID_PIOB,PIO_PERIPH_B,PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS3
|
||||
|
||||
// 79 .. 84 - "All pins" masks
|
||||
|
||||
// 79 - TWI0 all pins
|
||||
{ PIOA, PIO_PA17A_TWD0|PIO_PA18A_TWCK0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
// 80 - TWI1 all pins
|
||||
{ PIOB, PIO_PB12A_TWD1|PIO_PB13A_TWCK1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
// 81 - UART (Serial) all pins
|
||||
{ PIOA, PIO_PA8A_URXD|PIO_PA9A_UTXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
// 82 - USART0 (Serial1) all pins
|
||||
{ PIOA, PIO_PA11A_TXD0|PIO_PA10A_RXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
// 83 - USART1 (Serial2) all pins
|
||||
{ PIOA, PIO_PA13A_TXD1|PIO_PA12A_RXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
// 84 - USART3 (Serial3) all pins
|
||||
{ PIOD, PIO_PD4B_TXD3|PIO_PD5B_RXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
|
||||
// 85 - USB
|
||||
{ PIOB, PIO_PB11A_UOTGID, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL,NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ID
|
||||
// { PIOB, PIO_PB11A_UOTGID|PIO_PB10A_UOTGVBOF, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL,NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ID - VBOF
|
||||
// 86 - SPI CS2
|
||||
{ PIOB, PIO_PB21B_SPI0_NPCS2, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS2
|
||||
|
||||
// 87 - SPI CS1
|
||||
{ PIOA, PIO_PA29A_SPI0_NPCS1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS1
|
||||
|
||||
// 88/89 - CANRX1/CANTX1 (same physical pin for 66/53)
|
||||
{ PIOB, PIO_PB15A_CANRX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANRX1
|
||||
{ PIOB, PIO_PB14A_CANTX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANTX1
|
||||
|
||||
// 90 .. 91 - "All CAN pins" masks
|
||||
// 90 - CAN0 all pins
|
||||
{ PIOA, PIO_PA1A_CANRX0|PIO_PA0A_CANTX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
// 91 - CAN1 all pins
|
||||
{ PIOB, PIO_PB15A_CANRX1|PIO_PB14A_CANTX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
|
||||
// 92 .. 99 placeholders, future-proofing.
|
||||
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
// 100 - 108 extra SAM3X8E pins, not wired on Due
|
||||
{ PIOA, PIO_PA5, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 100
|
||||
{ PIOC, PIO_PC27, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 101
|
||||
{ PIOA, PIO_PA0, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 102
|
||||
{ PIOA, PIO_PA1, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 103
|
||||
{ PIOC, PIO_PC11, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 104
|
||||
{ PIOC, PIO_PC8B_PWML3, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH3, NOT_ON_TIMER }, // PWM 105
|
||||
{ PIOC, PIO_PC2B_PWML0, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH0, NOT_ON_TIMER }, // PWM 106
|
||||
{ PIOC, PIO_PC6B_PWML2, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH2, NOT_ON_TIMER }, //PWM 107
|
||||
{ PIOC, PIO_PC20, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, //PWM 108
|
||||
// 109 .. 114
|
||||
{ PIOA, PIO_PA20A_MCCDA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN_HSMCI_MCCDA_GPIO 109
|
||||
{ PIOA, PIO_PA19A_MCCK, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN_HSMCI_MCCK_GPIO 110
|
||||
{ PIOA, PIO_PA21A_MCDA0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN_HSMCI_MCDA0_GPIO 111
|
||||
{ PIOA, PIO_PA22A_MCDA1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN_HSMCI_MCDA1_GPIO 112
|
||||
{ PIOA, PIO_PA23A_MCDA2, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN_HSMCI_MCDA2_GPIO 113
|
||||
{ PIOA, PIO_PA24A_MCDA3, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN_HSMCI_MCDA3_GPIO 114
|
||||
// 115 .. 124 - ETHERNET MAC
|
||||
{ PIOB, PIO_PB0A_ETXCK, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ETXCK 115
|
||||
{ PIOB, PIO_PB1A_ETXEN, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ETXEN 116
|
||||
{ PIOB, PIO_PB2A_ETX0, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ETX0 117
|
||||
{ PIOB, PIO_PB3A_ETX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ETX1 118
|
||||
{ PIOB, PIO_PB4A_ECRSDV, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ECRSDV 119
|
||||
{ PIOB, PIO_PB5A_ERX0, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ERX0 120
|
||||
{ PIOB, PIO_PB6A_ERX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ERX1 121
|
||||
{ PIOB, PIO_PB7A_ERXER, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ERXER 122
|
||||
{ PIOB, PIO_PB8A_EMDC, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // EMDC 123
|
||||
{ PIOB, PIO_PB9A_EMDIO, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // EMDIO 124
|
||||
// 125
|
||||
{ PIOB, PIO_PB24, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 125
|
||||
{ PIOB, PIO_PB21X1_AD14, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC0, ADC14, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 126 - PB21 with enabled ADC
|
||||
{ PIOB, PIO_PB13X1_AD9, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC0, ADC9, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 127 - PB13 with enabled ACD AD9
|
||||
{ PIOB, PIO_PB22, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 128 - PB22 E1 Enabled
|
||||
{ PIOB, PIO_PB10A_UOTGVBOF, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL,NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ID - VBOF 129
|
||||
|
||||
// END
|
||||
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }
|
||||
} ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* UART objects
|
||||
*/
|
||||
RingBuffer rx_buffer1;
|
||||
|
||||
UARTClass Serial(UART, UART_IRQn, ID_UART, &rx_buffer1);
|
||||
void serialEvent() __attribute__((weak));
|
||||
void serialEvent() { }
|
||||
|
||||
// IT handlers
|
||||
void UART_Handler(void)
|
||||
{
|
||||
Serial.IrqHandler();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/*
|
||||
* USART objects
|
||||
*/
|
||||
RingBuffer rx_buffer2;
|
||||
RingBuffer rx_buffer3;
|
||||
RingBuffer rx_buffer4;
|
||||
|
||||
USARTClass Serial1(USART0, USART0_IRQn, ID_USART0, &rx_buffer2);
|
||||
void serialEvent1() __attribute__((weak));
|
||||
void serialEvent1() { }
|
||||
USARTClass Serial2(USART1, USART1_IRQn, ID_USART1, &rx_buffer3);
|
||||
void serialEvent2() __attribute__((weak));
|
||||
void serialEvent2() { }
|
||||
USARTClass Serial3(USART3, USART3_IRQn, ID_USART3, &rx_buffer4);
|
||||
void serialEvent3() __attribute__((weak));
|
||||
void serialEvent3() { }
|
||||
|
||||
// IT handlers
|
||||
void USART0_Handler(void)
|
||||
{
|
||||
Serial1.IrqHandler();
|
||||
}
|
||||
|
||||
void USART1_Handler(void)
|
||||
{
|
||||
Serial2.IrqHandler();
|
||||
}
|
||||
|
||||
void USART3_Handler(void)
|
||||
{
|
||||
Serial3.IrqHandler();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void serialEventRun(void)
|
||||
{
|
||||
if (Serial.available()) serialEvent();
|
||||
if (Serial1.available()) serialEvent1();
|
||||
if (Serial2.available()) serialEvent2();
|
||||
if (Serial3.available()) serialEvent3();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void __libc_init_array(void);
|
||||
|
||||
void init( void )
|
||||
{
|
||||
SystemInit();
|
||||
|
||||
// Set Systick to 1ms interval, common to all SAM3 variants
|
||||
if (SysTick_Config(SystemCoreClock / 1000))
|
||||
{
|
||||
// Capture error
|
||||
while (true);
|
||||
}
|
||||
|
||||
// Disable watchdog
|
||||
//WDT_Disable(WDT);
|
||||
// Initialize C library
|
||||
__libc_init_array();
|
||||
|
||||
// Disable pull-up on every pin
|
||||
for (int i = 0; i < PINS_COUNT; i++)
|
||||
digitalWrite(i, LOW);
|
||||
|
||||
// Enable parallel access on PIO output data registers
|
||||
PIOA->PIO_OWER = 0xFFFFFFFF;
|
||||
PIOB->PIO_OWER = 0xFFFFFFFF;
|
||||
PIOC->PIO_OWER = 0xFFFFFFFF;
|
||||
PIOD->PIO_OWER = 0xFFFFFFFF;
|
||||
|
||||
// Initialize Serial port U(S)ART pins
|
||||
PIO_Configure(
|
||||
g_APinDescription[PINS_UART].pPort,
|
||||
g_APinDescription[PINS_UART].ulPinType,
|
||||
g_APinDescription[PINS_UART].ulPin,
|
||||
g_APinDescription[PINS_UART].ulPinConfiguration);
|
||||
digitalWrite(0, HIGH); // Enable pullup for RX0
|
||||
PIO_Configure(
|
||||
g_APinDescription[PINS_USART0].pPort,
|
||||
g_APinDescription[PINS_USART0].ulPinType,
|
||||
g_APinDescription[PINS_USART0].ulPin,
|
||||
g_APinDescription[PINS_USART0].ulPinConfiguration);
|
||||
PIO_Configure(
|
||||
g_APinDescription[PINS_USART1].pPort,
|
||||
g_APinDescription[PINS_USART1].ulPinType,
|
||||
g_APinDescription[PINS_USART1].ulPin,
|
||||
g_APinDescription[PINS_USART1].ulPinConfiguration);
|
||||
PIO_Configure(
|
||||
g_APinDescription[PINS_USART3].pPort,
|
||||
g_APinDescription[PINS_USART3].ulPinType,
|
||||
g_APinDescription[PINS_USART3].ulPin,
|
||||
g_APinDescription[PINS_USART3].ulPinConfiguration);
|
||||
|
||||
// Initialize USB pins
|
||||
PIO_Configure(
|
||||
g_APinDescription[PINS_USB].pPort,
|
||||
g_APinDescription[PINS_USB].ulPinType,
|
||||
g_APinDescription[PINS_USB].ulPin,
|
||||
g_APinDescription[PINS_USB].ulPinConfiguration);
|
||||
|
||||
// Initialize CAN pins
|
||||
PIO_Configure(
|
||||
g_APinDescription[PINS_CAN0].pPort,
|
||||
g_APinDescription[PINS_CAN0].ulPinType,
|
||||
g_APinDescription[PINS_CAN0].ulPin,
|
||||
g_APinDescription[PINS_CAN0].ulPinConfiguration);
|
||||
PIO_Configure(
|
||||
g_APinDescription[PINS_CAN1].pPort,
|
||||
g_APinDescription[PINS_CAN1].ulPinType,
|
||||
g_APinDescription[PINS_CAN1].ulPin,
|
||||
g_APinDescription[PINS_CAN1].ulPinConfiguration);
|
||||
|
||||
// Initialize Analog Controller
|
||||
pmc_enable_periph_clk(ID_ADC);
|
||||
adc_init(ADC, SystemCoreClock, ADC_FREQ_MAX, ADC_STARTUP_FAST);
|
||||
adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1);
|
||||
adc_configure_trigger(ADC, ADC_TRIG_SW, 0); // Disable hardware trigger.
|
||||
adc_disable_interrupt(ADC, 0xFFFFFFFF); // Disable all ADC interrupts.
|
||||
adc_disable_all_channel(ADC);
|
||||
|
||||
// Initialize analogOutput module
|
||||
analogOutputInit();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,891 +0,0 @@
|
|||
// Copyright (c) 2010, Peter Barrett
|
||||
/*
|
||||
** Permission to use, copy, modify, and/or distribute this software for
|
||||
** any purpose with or without fee is hereby granted, provided that the
|
||||
** above copyright notice and this permission notice appear in all copies.
|
||||
**
|
||||
** THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
||||
** WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
||||
** WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR
|
||||
** BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES
|
||||
** OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
|
||||
** WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||
** ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
** SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "USBAPI.h"
|
||||
#include "Reset.h"
|
||||
#include <stdio.h>
|
||||
|
||||
//#define TRACE_CORE(x) x
|
||||
#define TRACE_CORE(x)
|
||||
|
||||
static const uint32_t EndPoints[] =
|
||||
{
|
||||
EP_TYPE_CONTROL,
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
EP_TYPE_INTERRUPT_IN, // CDC_ENDPOINT_ACM
|
||||
EP_TYPE_BULK_OUT, // CDC_ENDPOINT_OUT
|
||||
EP_TYPE_BULK_IN, // CDC_ENDPOINT_IN
|
||||
#endif
|
||||
|
||||
#ifdef HID_ENABLED
|
||||
EP_TYPE_INTERRUPT_IN_HID // HID_ENDPOINT_INT
|
||||
#endif
|
||||
};
|
||||
|
||||
/** Pulse generation counters to keep track of the number of milliseconds remaining for each pulse type */
|
||||
#define TX_RX_LED_PULSE_MS 100
|
||||
volatile uint8_t TxLEDPulse; /**< Milliseconds remaining for data Tx LED pulse */
|
||||
volatile uint8_t RxLEDPulse; /**< Milliseconds remaining for data Rx LED pulse */
|
||||
static char isRemoteWakeUpEnabled = 0;
|
||||
static char isEndpointHalt = 0;
|
||||
//==================================================================
|
||||
//==================================================================
|
||||
|
||||
extern const uint16_t STRING_LANGUAGE[];
|
||||
extern const uint8_t STRING_PRODUCT[];
|
||||
extern const uint8_t STRING_MANUFACTURER[];
|
||||
extern const DeviceDescriptor USB_DeviceDescriptor;
|
||||
extern const DeviceDescriptor USB_DeviceDescriptorA;
|
||||
|
||||
const uint16_t STRING_LANGUAGE[2] = {
|
||||
(3<<8) | (2+2),
|
||||
0x0409 // English
|
||||
};
|
||||
|
||||
#ifndef USB_PRODUCT
|
||||
// Use a hardcoded product name if none is provided
|
||||
#if USB_PID == USB_PID_DUE
|
||||
#define USB_PRODUCT "Arduino Due"
|
||||
#else
|
||||
#define USB_PRODUCT "USB IO Board"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const uint8_t STRING_PRODUCT[] = USB_PRODUCT;
|
||||
|
||||
#if USB_VID == 0x2341
|
||||
# if defined(USB_MANUFACTURER)
|
||||
# undef USB_MANUFACTURER
|
||||
# endif
|
||||
# define USB_MANUFACTURER "Arduino LLC"
|
||||
#elif !defined(USB_MANUFACTURER)
|
||||
// Fall through to unknown if no manufacturer name was provided in a macro
|
||||
# define USB_MANUFACTURER "Unknown"
|
||||
#endif
|
||||
|
||||
const uint8_t STRING_MANUFACTURER[12] = USB_MANUFACTURER;
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
#define DEVICE_CLASS 0x02
|
||||
#else
|
||||
#define DEVICE_CLASS 0x00
|
||||
#endif
|
||||
|
||||
// DEVICE DESCRIPTOR
|
||||
const DeviceDescriptor USB_DeviceDescriptor =
|
||||
D_DEVICE(0x00,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1);
|
||||
|
||||
const DeviceDescriptor USB_DeviceDescriptorA =
|
||||
D_DEVICE(DEVICE_CLASS,0x00,0x00,64,USB_VID,USB_PID,0x100,IMANUFACTURER,IPRODUCT,0,1);
|
||||
|
||||
const DeviceDescriptor USB_DeviceQualifier =
|
||||
D_QUALIFIER(0x00,0x00,0x00,64,1);
|
||||
|
||||
//! 7.1.20 Test Mode Support
|
||||
static const unsigned char test_packet_buffer[] = {
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // JKJKJKJK * 9
|
||||
0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xAA, // JJKKJJKK * 8
|
||||
0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE,0xEE, // JJJJKKKK * 8
|
||||
0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, // JJJJJJJKKKKKKK * 8
|
||||
0x7F,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD, // JJJJJJJK * 8
|
||||
0xFC,0x7E,0xBF,0xDF,0xEF,0xF7,0xFB,0xFD,0x7E // {JKKKKKKK * 10}, JK
|
||||
};
|
||||
|
||||
//==================================================================
|
||||
//==================================================================
|
||||
|
||||
volatile uint32_t _usbConfiguration = 0;
|
||||
volatile uint32_t _usbInitialized = 0;
|
||||
uint32_t _usbSetInterface = 0;
|
||||
uint32_t _cdcComposite = 0;
|
||||
|
||||
//==================================================================
|
||||
//==================================================================
|
||||
|
||||
#define USB_RECV_TIMEOUT
|
||||
class LockEP
|
||||
{
|
||||
irqflags_t flags;
|
||||
public:
|
||||
LockEP(uint32_t ep) : flags(cpu_irq_save())
|
||||
{
|
||||
}
|
||||
~LockEP()
|
||||
{
|
||||
cpu_irq_restore(flags);
|
||||
}
|
||||
};
|
||||
|
||||
// Number of bytes, assumes a rx endpoint
|
||||
uint32_t USBD_Available(uint32_t ep)
|
||||
{
|
||||
LockEP lock(ep);
|
||||
return UDD_FifoByteCount(ep & 0xF);
|
||||
}
|
||||
|
||||
// Non Blocking receive
|
||||
// Return number of bytes read
|
||||
uint32_t USBD_Recv(uint32_t ep, void* d, uint32_t len)
|
||||
{
|
||||
if (!_usbConfiguration)
|
||||
return -1;
|
||||
|
||||
LockEP lock(ep);
|
||||
uint32_t n = UDD_FifoByteCount(ep & 0xF);
|
||||
len = min(n,len);
|
||||
n = len;
|
||||
uint8_t* dst = (uint8_t*)d;
|
||||
while (n--)
|
||||
*dst++ = UDD_Recv8(ep & 0xF);
|
||||
if (len && !UDD_FifoByteCount(ep & 0xF)) // release empty buffer
|
||||
UDD_ReleaseRX(ep & 0xF);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
// Recv 1 byte if ready
|
||||
uint32_t USBD_Recv(uint32_t ep)
|
||||
{
|
||||
uint8_t c;
|
||||
if (USBD_Recv(ep & 0xF, &c, 1) != 1)
|
||||
return -1;
|
||||
else
|
||||
return c;
|
||||
}
|
||||
|
||||
// Space in send EP
|
||||
//uint32_t USBD_SendSpace(uint32_t ep)
|
||||
//{
|
||||
//LockEP lock(ep);
|
||||
//// if (!UDD_ReadWriteAllowed(ep & 0xF))
|
||||
////{
|
||||
////printf("pb "); // UOTGHS->UOTGHS_DEVEPTISR[%d]=0x%X\n\r", ep, UOTGHS->UOTGHS_DEVEPTISR[ep]);
|
||||
////return 0;
|
||||
////}
|
||||
|
||||
//if(ep==0) return 64 - UDD_FifoByteCount(ep & 0xF); // EP0_SIZE jcb
|
||||
//else return 512 - UDD_FifoByteCount(ep & 0xF); // EPX_SIZE jcb
|
||||
//}
|
||||
|
||||
// Blocking Send of data to an endpoint
|
||||
uint32_t USBD_Send(uint32_t ep, const void* d, uint32_t len)
|
||||
{
|
||||
uint32_t n;
|
||||
int r = len;
|
||||
const uint8_t* data = (const uint8_t*)d;
|
||||
|
||||
if (!_usbConfiguration)
|
||||
{
|
||||
TRACE_CORE(printf("pb conf\n\r");)
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (len)
|
||||
{
|
||||
if(ep==0) n = EP0_SIZE;
|
||||
else n = EPX_SIZE;
|
||||
if (n > len)
|
||||
n = len;
|
||||
len -= n;
|
||||
int count=0;
|
||||
while( UOTGHS_DEVEPTISR_TXINI != (UOTGHS->UOTGHS_DEVEPTISR[ep & 0xF] & UOTGHS_DEVEPTISR_TXINI ))
|
||||
{
|
||||
count++;
|
||||
if (count>10000) return len;
|
||||
}
|
||||
UDD_Send(ep & 0xF, data, n);
|
||||
data += n;
|
||||
}
|
||||
//TXLED1; // light the TX LED
|
||||
//TxLEDPulse = TX_RX_LED_PULSE_MS;
|
||||
return r;
|
||||
}
|
||||
|
||||
int _cmark;
|
||||
int _cend;
|
||||
|
||||
void USBD_InitControl(int end)
|
||||
{
|
||||
_cmark = 0;
|
||||
_cend = end;
|
||||
}
|
||||
|
||||
// Clipped by _cmark/_cend
|
||||
int USBD_SendControl(uint8_t flags, const void* d, uint32_t len)
|
||||
{
|
||||
const uint8_t* data = (const uint8_t*)d;
|
||||
uint32_t length = len;
|
||||
uint32_t sent = 0;
|
||||
uint32_t pos = 0;
|
||||
|
||||
TRACE_CORE(printf("=> USBD_SendControl TOTAL len=%lu\r\n", len);)
|
||||
|
||||
if (_cmark < _cend)
|
||||
{
|
||||
while (len > 0)
|
||||
{
|
||||
sent = UDD_Send(EP0, data + pos, len);
|
||||
TRACE_CORE(printf("=> USBD_SendControl sent=%lu\r\n", sent);)
|
||||
pos += sent;
|
||||
len -= sent;
|
||||
}
|
||||
}
|
||||
|
||||
_cmark += length;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
// Send a USB descriptor string. The string is stored as a
|
||||
// plain ASCII string but is sent out as UTF-16 with the
|
||||
// correct 2-byte prefix
|
||||
static bool USB_SendStringDescriptor(const uint8_t *string, int wLength) {
|
||||
uint16_t buff[64];
|
||||
int l = 1;
|
||||
wLength-=2;
|
||||
while (*string && wLength>0) {
|
||||
buff[l++] = (uint8_t)(*string++);
|
||||
wLength-=2;
|
||||
}
|
||||
buff[0] = (3<<8) | (l*2);
|
||||
return USBD_SendControl(0, (uint8_t*)buff, l*2);
|
||||
}
|
||||
|
||||
// Does not timeout or cross fifo boundaries
|
||||
// Will only work for transfers <= 64 bytes
|
||||
// TODO
|
||||
int USBD_RecvControl(void* d, uint32_t len)
|
||||
{
|
||||
UDD_WaitOUT();
|
||||
UDD_Recv(EP0, (uint8_t*)d, len);
|
||||
UDD_ClearOUT();
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
// Handle CLASS_INTERFACE requests
|
||||
bool USBD_ClassInterfaceRequest(Setup& setup)
|
||||
{
|
||||
uint8_t i = setup.wIndex;
|
||||
|
||||
TRACE_CORE(printf("=> USBD_ClassInterfaceRequest\r\n");)
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
if (CDC_ACM_INTERFACE == i)
|
||||
{
|
||||
return CDC_Setup(setup);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HID_ENABLED
|
||||
if (HID_INTERFACE == i)
|
||||
{
|
||||
return HID_Setup(setup);
|
||||
}
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
int USBD_SendInterfaces(void)
|
||||
{
|
||||
int total = 0;
|
||||
uint8_t interfaces = 0;
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
total = CDC_GetInterface(&interfaces);
|
||||
#endif
|
||||
|
||||
#ifdef HID_ENABLED
|
||||
total += HID_GetInterface(&interfaces);
|
||||
#endif
|
||||
|
||||
total = total; // Get rid of compiler warning
|
||||
TRACE_CORE(printf("=> USBD_SendInterfaces, total=%d interfaces=%d\r\n", total, interfaces);)
|
||||
return interfaces;
|
||||
}
|
||||
|
||||
int USBD_SendOtherInterfaces(void)
|
||||
{
|
||||
int total = 0;
|
||||
uint8_t interfaces = 0;
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
total = CDC_GetOtherInterface(&interfaces);
|
||||
#endif
|
||||
|
||||
#ifdef HID_ENABLED
|
||||
total += HID_GetInterface(&interfaces);
|
||||
#endif
|
||||
|
||||
total = total; // Get rid of compiler warning
|
||||
TRACE_CORE(printf("=> USBD_SendInterfaces, total=%d interfaces=%d\r\n", total, interfaces);)
|
||||
return interfaces;
|
||||
}
|
||||
|
||||
// Construct a dynamic configuration descriptor
|
||||
// This really needs dynamic endpoint allocation etc
|
||||
// TODO
|
||||
static bool USBD_SendConfiguration(int maxlen)
|
||||
{
|
||||
// Count and measure interfaces
|
||||
USBD_InitControl(0);
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration _cmark1=%d\r\n", _cmark);)
|
||||
int interfaces = USBD_SendInterfaces();
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration _cmark2=%d\r\n", _cmark);)
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration sizeof=%d\r\n", sizeof(ConfigDescriptor));)
|
||||
|
||||
_Pragma("pack(1)")
|
||||
ConfigDescriptor config = D_CONFIG(_cmark + sizeof(ConfigDescriptor),interfaces);
|
||||
_Pragma("pack()")
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration clen=%d\r\n", config.clen);)
|
||||
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration maxlen=%d\r\n", maxlen);)
|
||||
|
||||
// Now send them
|
||||
USBD_InitControl(maxlen);
|
||||
USBD_SendControl(0,&config,sizeof(ConfigDescriptor));
|
||||
USBD_SendInterfaces();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool USBD_SendOtherConfiguration(int maxlen)
|
||||
{
|
||||
// Count and measure interfaces
|
||||
USBD_InitControl(0);
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration _cmark1=%d\r\n", _cmark);)
|
||||
int interfaces = USBD_SendOtherInterfaces();
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration _cmark2=%d\r\n", _cmark);)
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration sizeof=%d\r\n", sizeof(ConfigDescriptor));)
|
||||
|
||||
_Pragma("pack(1)")
|
||||
ConfigDescriptor config = D_OTHERCONFIG(_cmark + sizeof(ConfigDescriptor),interfaces);
|
||||
_Pragma("pack()")
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration clen=%d\r\n", config.clen);)
|
||||
|
||||
//TRACE_CORE(printf("=> USBD_SendConfiguration maxlen=%d\r\n", maxlen);)
|
||||
|
||||
// Now send them
|
||||
USBD_InitControl(maxlen);
|
||||
USBD_SendControl(0,&config,sizeof(ConfigDescriptor));
|
||||
USBD_SendOtherInterfaces();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool USBD_SendDescriptor(Setup& setup)
|
||||
{
|
||||
uint8_t t = setup.wValueH;
|
||||
uint8_t desc_length = 0;
|
||||
const uint8_t* desc_addr = 0;
|
||||
|
||||
if (USB_CONFIGURATION_DESCRIPTOR_TYPE == t)
|
||||
{
|
||||
TRACE_CORE(printf("=> USBD_SendDescriptor : USB_CONFIGURATION_DESCRIPTOR_TYPE length=%d\r\n", setup.wLength);)
|
||||
return USBD_SendConfiguration(setup.wLength);
|
||||
}
|
||||
|
||||
USBD_InitControl(setup.wLength);
|
||||
#ifdef HID_ENABLED
|
||||
if (HID_REPORT_DESCRIPTOR_TYPE == t)
|
||||
{
|
||||
TRACE_CORE(puts("=> USBD_SendDescriptor : HID_REPORT_DESCRIPTOR_TYPE\r\n");)
|
||||
return HID_GetDescriptor(t);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (USB_DEVICE_DESCRIPTOR_TYPE == t)
|
||||
{
|
||||
TRACE_CORE(puts("=> USBD_SendDescriptor : USB_DEVICE_DESCRIPTOR_TYPE\r\n");)
|
||||
if (setup.wLength == 8)
|
||||
{
|
||||
_cdcComposite = 1;
|
||||
}
|
||||
desc_addr = _cdcComposite ? (const uint8_t*)&USB_DeviceDescriptorA : (const uint8_t*)&USB_DeviceDescriptor;
|
||||
if( *desc_addr > setup.wLength ) {
|
||||
desc_length = setup.wLength;
|
||||
}
|
||||
}
|
||||
else if (USB_STRING_DESCRIPTOR_TYPE == t)
|
||||
{
|
||||
TRACE_CORE(puts("=> USBD_SendDescriptor : USB_STRING_DESCRIPTOR_TYPE\r\n");)
|
||||
if (setup.wValueL == 0) {
|
||||
desc_addr = (const uint8_t*)&STRING_LANGUAGE;
|
||||
}
|
||||
else if (setup.wValueL == IPRODUCT) {
|
||||
return USB_SendStringDescriptor(STRING_PRODUCT, setup.wLength);
|
||||
}
|
||||
else if (setup.wValueL == IMANUFACTURER) {
|
||||
return USB_SendStringDescriptor(STRING_MANUFACTURER, setup.wLength);
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
if( *desc_addr > setup.wLength ) {
|
||||
desc_length = setup.wLength;
|
||||
}
|
||||
}
|
||||
else if (USB_DEVICE_QUALIFIER == t)
|
||||
{
|
||||
// Device qualifier descriptor requested
|
||||
desc_addr = (const uint8_t*)&USB_DeviceQualifier;
|
||||
if( *desc_addr > setup.wLength ) {
|
||||
desc_length = setup.wLength;
|
||||
}
|
||||
}
|
||||
else if (USB_OTHER_SPEED_CONFIGURATION == t)
|
||||
{
|
||||
// Other configuration descriptor requested
|
||||
return USBD_SendOtherConfiguration(setup.wLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("Device ERROR");
|
||||
}
|
||||
|
||||
if (desc_addr == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (desc_length == 0)
|
||||
{
|
||||
desc_length = *desc_addr;
|
||||
}
|
||||
|
||||
TRACE_CORE(printf("=> USBD_SendDescriptor : desc_addr=%p desc_length=%d\r\n", desc_addr, desc_length);)
|
||||
USBD_SendControl(0, desc_addr, desc_length);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void USB_SendZlp( void )
|
||||
{
|
||||
while( UOTGHS_DEVEPTISR_TXINI != (UOTGHS->UOTGHS_DEVEPTISR[0] & UOTGHS_DEVEPTISR_TXINI ) )
|
||||
{
|
||||
if((UOTGHS->UOTGHS_DEVISR & UOTGHS_DEVISR_SUSP) == UOTGHS_DEVISR_SUSP)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
UOTGHS->UOTGHS_DEVEPTICR[0] = UOTGHS_DEVEPTICR_TXINIC;
|
||||
}
|
||||
|
||||
|
||||
static void Test_Mode_Support( uint8_t wIndex )
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t *ptr_dest = (uint8_t *) &udd_get_endpoint_fifo_access8(2);
|
||||
|
||||
switch( wIndex )
|
||||
{
|
||||
case 4:
|
||||
//Test mode Test_Packet:
|
||||
//Upon command, a port must repetitively transmit the following test packet until
|
||||
//the exit action is taken. This enables the testing of rise and fall times, eye
|
||||
//patterns, jitter, and any other dynamic waveform specifications.
|
||||
//The test packet is made up by concatenating the following strings.
|
||||
//(Note: For J/K NRZI data, and for NRZ data, the bit on the left is the first one
|
||||
//transmitted. "S" indicates that a bit stuff occurs, which inserts an "extra" NRZI data bit.
|
||||
//"* N" is used to indicate N occurrences of a string of bits or symbols.)
|
||||
//A port in Test_Packet mode must send this packet repetitively. The inter-packet timing
|
||||
//must be no less than the minimum allowable inter-packet gap as defined in Section 7.1.18 and
|
||||
//no greater than 125 us.
|
||||
|
||||
// Send ZLP
|
||||
USB_SendZlp();
|
||||
|
||||
UOTGHS->UOTGHS_DEVDMA[0].UOTGHS_DEVDMACONTROL = 0; // raz
|
||||
UOTGHS->UOTGHS_DEVDMA[1].UOTGHS_DEVDMACONTROL = 0; // raz
|
||||
|
||||
// Configure endpoint 2, 64 bytes, direction IN, type BULK, 1 bank
|
||||
UOTGHS->UOTGHS_DEVEPTCFG[2] = UOTGHS_DEVEPTCFG_EPSIZE_64_BYTE
|
||||
| UOTGHS_DEVEPTCFG_EPDIR_IN
|
||||
| UOTGHS_DEVEPTCFG_EPTYPE_BLK
|
||||
| UOTGHS_DEVEPTCFG_EPBK_1_BANK;
|
||||
// Check if the configuration is ok
|
||||
UOTGHS->UOTGHS_DEVEPTCFG[2] |= UOTGHS_DEVEPTCFG_ALLOC;
|
||||
while((UOTGHS->UOTGHS_DEVEPTISR[2]&UOTGHS_DEVEPTISR_CFGOK)==0) {}
|
||||
UOTGHS->UOTGHS_DEVEPT |= UOTGHS_DEVEPT_EPEN2;
|
||||
// Write FIFO
|
||||
for( i=0; i<sizeof(test_packet_buffer); i++)
|
||||
{
|
||||
ptr_dest[i] = test_packet_buffer[i];;
|
||||
}
|
||||
// Tst PACKET
|
||||
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_TSTPCKT;
|
||||
// Send packet
|
||||
UOTGHS->UOTGHS_DEVEPTICR[2] = UOTGHS_DEVEPTICR_TXINIC;
|
||||
UOTGHS->UOTGHS_DEVEPTIDR[2] = UOTGHS_DEVEPTIDR_FIFOCONC;
|
||||
for(;;);
|
||||
// break;
|
||||
|
||||
case 1:
|
||||
//Test mode Test_J:
|
||||
//Upon command, a port's transceiver must enter the high-speed J state and remain in that
|
||||
//state until the exit action is taken. This enables the testing of the high output drive
|
||||
//level on the D+ line.
|
||||
// Send a ZLP
|
||||
USB_SendZlp();
|
||||
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_TSTJ;
|
||||
for(;;);
|
||||
// break;
|
||||
|
||||
case 2:
|
||||
//Test mode Test_K:
|
||||
//Upon command, a port's transceiver must enter the high-speed K state and remain in
|
||||
//that state until the exit action is taken. This enables the testing of the high output drive
|
||||
//level on the D- line.
|
||||
// Send a ZLP
|
||||
USB_SendZlp();
|
||||
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_TSTK;
|
||||
for(;;);
|
||||
// break;
|
||||
|
||||
case 3:
|
||||
//Test mode Test_SE0_NAK:
|
||||
//Upon command, a port's transceiver must enter the high-speed receive mode
|
||||
//and remain in that mode until the exit action is taken. This enables the testing
|
||||
//of output impedance, low level output voltage, and loading characteristics.
|
||||
//In addition, while in this mode, upstream facing ports (and only upstream facing ports)
|
||||
//must respond to any IN token packet with a NAK handshake (only if the packet CRC is
|
||||
//determined to be correct) within the normal allowed device response time. This enables testing of
|
||||
//the device squelch level circuitry and, additionally, provides a general purpose stimulus/response
|
||||
//test for basic functional testing.
|
||||
|
||||
// Send a ZLP
|
||||
USB_SendZlp();
|
||||
UOTGHS->UOTGHS_DEVIDR = UOTGHS_DEVIDR_SUSPEC
|
||||
| UOTGHS_DEVIDR_MSOFEC
|
||||
| UOTGHS_DEVIDR_SOFEC
|
||||
| UOTGHS_DEVIDR_EORSTEC
|
||||
| UOTGHS_DEVIDR_WAKEUPEC
|
||||
| UOTGHS_DEVIDR_EORSMEC
|
||||
| UOTGHS_DEVIDR_UPRSMEC
|
||||
| UOTGHS_DEVIDR_PEP_0
|
||||
| UOTGHS_DEVIDR_PEP_1
|
||||
| UOTGHS_DEVIDR_PEP_2
|
||||
| UOTGHS_DEVIDR_PEP_3
|
||||
| UOTGHS_DEVIDR_PEP_4
|
||||
| UOTGHS_DEVIDR_PEP_5
|
||||
| UOTGHS_DEVIDR_PEP_6
|
||||
| UOTGHS_DEVIDR_DMA_1
|
||||
| UOTGHS_DEVIDR_DMA_2
|
||||
| UOTGHS_DEVIDR_DMA_3
|
||||
| UOTGHS_DEVIDR_DMA_4
|
||||
| UOTGHS_DEVIDR_DMA_5
|
||||
| UOTGHS_DEVIDR_DMA_6;
|
||||
for(;;);
|
||||
// break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//unsigned int iii=0;
|
||||
// Endpoint 0 interrupt
|
||||
static void USB_ISR(void)
|
||||
{
|
||||
// printf("ISR=0x%X\n\r", UOTGHS->UOTGHS_DEVISR); // jcb
|
||||
// if( iii++ > 1500 ) while(1); // jcb
|
||||
// End of bus reset
|
||||
if (Is_udd_reset())
|
||||
{
|
||||
TRACE_CORE(printf(">>> End of Reset\r\n");)
|
||||
|
||||
// Reset USB address to 0
|
||||
udd_configure_address(0);
|
||||
udd_enable_address();
|
||||
|
||||
// Configure EP 0
|
||||
UDD_InitEP(0, EP_TYPE_CONTROL);
|
||||
udd_enable_setup_received_interrupt(0);
|
||||
udd_enable_endpoint_interrupt(0);
|
||||
|
||||
_usbConfiguration = 0;
|
||||
udd_ack_reset();
|
||||
}
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
if (Is_udd_endpoint_interrupt(CDC_RX))
|
||||
{
|
||||
udd_ack_out_received(CDC_RX);
|
||||
|
||||
// Handle received bytes
|
||||
if (USBD_Available(CDC_RX))
|
||||
SerialUSB.accept();
|
||||
}
|
||||
|
||||
if (Is_udd_sof())
|
||||
{
|
||||
udd_ack_sof();
|
||||
// USBD_Flush(CDC_TX); // jcb
|
||||
}
|
||||
#endif
|
||||
|
||||
// EP 0 Interrupt
|
||||
if (Is_udd_endpoint_interrupt(0) )
|
||||
{
|
||||
if (!UDD_ReceivedSetupInt())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Setup setup;
|
||||
UDD_Recv(EP0, (uint8_t*)&setup, 8);
|
||||
UDD_ClearSetupInt();
|
||||
|
||||
uint8_t requestType = setup.bmRequestType;
|
||||
if (requestType & REQUEST_DEVICETOHOST)
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: IN Request\r\n");)
|
||||
UDD_WaitIN();
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: OUT Request\r\n");)
|
||||
UDD_ClearIN();
|
||||
}
|
||||
|
||||
bool ok = true;
|
||||
if (REQUEST_STANDARD == (requestType & REQUEST_TYPE))
|
||||
{
|
||||
// Standard Requests
|
||||
uint8_t r = setup.bRequest;
|
||||
if (GET_STATUS == r)
|
||||
{
|
||||
if( setup.bmRequestType == 0 ) // device
|
||||
{
|
||||
// Send the device status
|
||||
TRACE_CORE(puts(">>> EP0 Int: GET_STATUS\r\n");)
|
||||
// Check current configuration for power mode (if device is configured)
|
||||
// TODO
|
||||
// Check if remote wake-up is enabled
|
||||
// TODO
|
||||
UDD_Send8(EP0, 0); // TODO
|
||||
UDD_Send8(EP0, 0);
|
||||
}
|
||||
// if( setup.bmRequestType == 2 ) // Endpoint:
|
||||
else
|
||||
{
|
||||
// Send the endpoint status
|
||||
// Check if the endpoint if currently halted
|
||||
if( isEndpointHalt == 1 )
|
||||
UDD_Send8(EP0, 1); // TODO
|
||||
else
|
||||
UDD_Send8(EP0, 0); // TODO
|
||||
UDD_Send8(EP0, 0);
|
||||
}
|
||||
}
|
||||
else if (CLEAR_FEATURE == r)
|
||||
{
|
||||
// Check which is the selected feature
|
||||
if( setup.wValueL == 1) // DEVICEREMOTEWAKEUP
|
||||
{
|
||||
// Enable remote wake-up and send a ZLP
|
||||
if( isRemoteWakeUpEnabled == 1 )
|
||||
UDD_Send8(EP0, 1);
|
||||
else
|
||||
UDD_Send8(EP0, 0);
|
||||
UDD_Send8(EP0, 0);
|
||||
}
|
||||
else // if( setup.wValueL == 0) // ENDPOINTHALT
|
||||
{
|
||||
isEndpointHalt = 0; // TODO
|
||||
UDD_Send8(EP0, 0);
|
||||
UDD_Send8(EP0, 0);
|
||||
}
|
||||
|
||||
}
|
||||
else if (SET_FEATURE == r)
|
||||
{
|
||||
// Check which is the selected feature
|
||||
if( setup.wValueL == 1) // DEVICEREMOTEWAKEUP
|
||||
{
|
||||
// Enable remote wake-up and send a ZLP
|
||||
isRemoteWakeUpEnabled = 1;
|
||||
UDD_Send8(EP0, 0);
|
||||
}
|
||||
if( setup.wValueL == 0) // ENDPOINTHALT
|
||||
{
|
||||
// Halt endpoint
|
||||
isEndpointHalt = 1;
|
||||
//USBD_Halt(USBGenericRequest_GetEndpointNumber(pRequest));
|
||||
UDD_Send8(EP0, 0);
|
||||
}
|
||||
if( setup.wValueL == 2) // TEST_MODE
|
||||
{
|
||||
// 7.1.20 Test Mode Support, 9.4.9 SetFeature
|
||||
if( (setup.bmRequestType == 0 /*USBGenericRequest_DEVICE*/) &&
|
||||
((setup.wIndex & 0x000F) == 0) )
|
||||
{
|
||||
// the lower byte of wIndex must be zero
|
||||
// the most significant byte of wIndex is used to specify the specific test mode
|
||||
|
||||
UOTGHS->UOTGHS_DEVIDR &= ~UOTGHS_DEVIDR_SUSPEC;
|
||||
UOTGHS->UOTGHS_DEVCTRL |= UOTGHS_DEVCTRL_SPDCONF_HIGH_SPEED; // remove suspend ?
|
||||
|
||||
Test_Mode_Support( (setup.wIndex & 0xFF00)>>8 );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (SET_ADDRESS == r)
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: SET_ADDRESS\r\n");)
|
||||
UDD_WaitIN();
|
||||
UDD_SetAddress(setup.wValueL);
|
||||
}
|
||||
else if (GET_DESCRIPTOR == r)
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: GET_DESCRIPTOR\r\n");)
|
||||
ok = USBD_SendDescriptor(setup);
|
||||
}
|
||||
else if (SET_DESCRIPTOR == r)
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: SET_DESCRIPTOR\r\n");)
|
||||
ok = false;
|
||||
}
|
||||
else if (GET_CONFIGURATION == r)
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: GET_CONFIGURATION\r\n");)
|
||||
UDD_Send8(EP0, _usbConfiguration);
|
||||
}
|
||||
else if (SET_CONFIGURATION == r)
|
||||
{
|
||||
if (REQUEST_DEVICE == (requestType & REQUEST_RECIPIENT))
|
||||
{
|
||||
TRACE_CORE(printf(">>> EP0 Int: SET_CONFIGURATION REQUEST_DEVICE %d\r\n", setup.wValueL);)
|
||||
|
||||
UDD_InitEndpoints(EndPoints, (sizeof(EndPoints) / sizeof(EndPoints[0])));
|
||||
_usbConfiguration = setup.wValueL;
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
// Enable interrupt for CDC reception from host (OUT packet)
|
||||
udd_enable_out_received_interrupt(CDC_RX);
|
||||
udd_enable_endpoint_interrupt(CDC_RX);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: SET_CONFIGURATION failed!\r\n");)
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
else if (GET_INTERFACE == r)
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: GET_INTERFACE\r\n");)
|
||||
UDD_Send8(EP0, _usbSetInterface);
|
||||
}
|
||||
else if (SET_INTERFACE == r)
|
||||
{
|
||||
_usbSetInterface = setup.wValueL;
|
||||
TRACE_CORE(puts(">>> EP0 Int: SET_INTERFACE\r\n");)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: ClassInterfaceRequest\r\n");)
|
||||
|
||||
UDD_WaitIN(); // Workaround: need tempo here, else CDC serial won't open correctly
|
||||
|
||||
USBD_InitControl(setup.wLength); // Max length of transfer
|
||||
ok = USBD_ClassInterfaceRequest(setup);
|
||||
}
|
||||
|
||||
if (ok)
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: Send packet\r\n");)
|
||||
UDD_ClearIN();
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE_CORE(puts(">>> EP0 Int: Stall\r\n");)
|
||||
UDD_Stall();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void USBD_Flush(uint32_t ep)
|
||||
{
|
||||
if (UDD_FifoByteCount(ep))
|
||||
UDD_ReleaseTX(ep);
|
||||
}
|
||||
|
||||
// VBUS or counting frames
|
||||
// Any frame counting?
|
||||
uint32_t USBD_Connected(void)
|
||||
{
|
||||
uint8_t f = UDD_GetFrameNumber();
|
||||
|
||||
delay(3);
|
||||
|
||||
return f != UDD_GetFrameNumber();
|
||||
}
|
||||
|
||||
|
||||
//=======================================================================
|
||||
//=======================================================================
|
||||
|
||||
USBDevice_ USBDevice;
|
||||
|
||||
USBDevice_::USBDevice_()
|
||||
{
|
||||
UDD_SetStack(&USB_ISR);
|
||||
|
||||
if (UDD_Init() == 0UL)
|
||||
{
|
||||
_usbInitialized=1UL;
|
||||
}
|
||||
}
|
||||
|
||||
bool USBDevice_::attach(void)
|
||||
{
|
||||
if (_usbInitialized != 0UL)
|
||||
{
|
||||
UDD_Attach();
|
||||
_usbConfiguration = 0;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool USBDevice_::detach(void)
|
||||
{
|
||||
if (_usbInitialized != 0UL)
|
||||
{
|
||||
UDD_Detach();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for interrupts
|
||||
// TODO: VBUS detection
|
||||
bool USBDevice_::configured()
|
||||
{
|
||||
return _usbConfiguration;
|
||||
}
|
||||
|
||||
void USBDevice_::poll()
|
||||
{
|
||||
}
|
|
@ -1,496 +0,0 @@
|
|||
/*
|
||||
Copyright (c) 2011 Arduino. 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
|
||||
*/
|
||||
|
||||
#include "variant.h"
|
||||
|
||||
/*
|
||||
* DUE Board pin | PORT | Label
|
||||
* ----------------+--------+-------
|
||||
* 0 | PA8 | "RX0"
|
||||
* 1 | PA9 | "TX0"
|
||||
* 2 TIOA0 | PB25 |
|
||||
* 3 TIOA7 | PC28 |
|
||||
* 4 NPCS1 | PA29 |
|
||||
* TIOB6 | PC26 |
|
||||
* 5 TIOA6 | PC25 |
|
||||
* 6 PWML7 | PC24 |
|
||||
* 7 PWML6 | PC23 |
|
||||
* 8 PWML5 | PC22 |
|
||||
* 9 PWML4 | PC21 |
|
||||
* 10 NPCS0 | PA28 |
|
||||
* TIOB7 | PC29 |
|
||||
* 11 TIOA8 | PD7 |
|
||||
* 12 TIOB8 | PD8 |
|
||||
* 13 TIOB0 | PB27 | LED AMBER "L"
|
||||
* 14 TXD3 | PD4 | "TX3"
|
||||
* 15 RXD3 | PD5 | "RX3"
|
||||
* 16 TXD1 | PA13 | "TX2"
|
||||
* 17 RXD1 | PA12 | "RX2"
|
||||
* 18 TXD0 | PA11 | "TX1"
|
||||
* 19 RXD0 | PA10 | "RX1"
|
||||
* 20 | PB12 | "SDA"
|
||||
* 21 | PB13 | "SCL"
|
||||
* 22 | PB26 |
|
||||
* 23 | PA14 |
|
||||
* 24 | PA15 |
|
||||
* 25 | PD0 |
|
||||
* 26 | PD1 |
|
||||
* 27 | PD2 |
|
||||
* 28 | PD3 |
|
||||
* 29 | PD6 |
|
||||
* 30 | PD9 |
|
||||
* 31 | PA7 |
|
||||
* 32 | PD10 |
|
||||
* 33 | PC1 |
|
||||
* 34 | PC2 |
|
||||
* 35 | PC3 |
|
||||
* 36 | PC4 |
|
||||
* 37 | PC5 |
|
||||
* 38 | PC6 |
|
||||
* 39 | PC7 |
|
||||
* 40 | PC8 |
|
||||
* 41 | PC9 |
|
||||
* 42 | PA19 |
|
||||
* 43 | PA20 |
|
||||
* 44 | PC19 |
|
||||
* 45 | PC18 |
|
||||
* 46 | PC17 |
|
||||
* 47 | PC16 |
|
||||
* 48 | PC15 |
|
||||
* 49 | PC14 |
|
||||
* 50 | PC13 |
|
||||
* 51 | PC12 |
|
||||
* 52 NPCS2 | PB21 |
|
||||
* 53 | PB14 |
|
||||
* 54 | PA16 | "A0"
|
||||
* 55 | PA24 | "A1"
|
||||
* 56 | PA23 | "A2"
|
||||
* 57 | PA22 | "A3"
|
||||
* 58 TIOB2 | PA6 | "A4"
|
||||
* 69 | PA4 | "A5"
|
||||
* 60 TIOB1 | PA3 | "A6"
|
||||
* 61 TIOA1 | PA2 | "A7"
|
||||
* 62 | PB17 | "A8"
|
||||
* 63 | PB18 | "A9"
|
||||
* 64 | PB19 | "A10"
|
||||
* 65 | PB20 | "A11"
|
||||
* 66 | PB15 | "DAC0"
|
||||
* 67 | PB16 | "DAC1"
|
||||
* 68 | PA1 | "CANRX"
|
||||
* 69 | PA0 | "CANTX"
|
||||
* 70 | PA17 | "SDA1"
|
||||
* 71 | PA18 | "SCL1"
|
||||
* 72 | PC30 | LED AMBER "RX"
|
||||
* 73 | PA21 | LED AMBER "TX"
|
||||
* 74 MISO | PA25 |
|
||||
* 75 MOSI | PA26 |
|
||||
* 76 SCLK | PA27 |
|
||||
* 77 NPCS0 | PA28 |
|
||||
* 78 NPCS3 | PB23 | unconnected!
|
||||
*
|
||||
* USB pin | PORT
|
||||
* ----------------+--------
|
||||
* ID | PB11
|
||||
* VBOF | PB10
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Pins descriptions
|
||||
*/
|
||||
extern const PinDescription g_APinDescription[]=
|
||||
{
|
||||
// 0 .. 53 - Digital pins
|
||||
// ----------------------
|
||||
// 0/1 - UART (Serial)
|
||||
{ PIOA, PIO_PA8A_URXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // URXD
|
||||
{ PIOA, PIO_PA9A_UTXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // UTXD
|
||||
|
||||
// 2
|
||||
{ PIOB, PIO_PB25B_TIOA0, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC0_CHA0 }, // TIOA0
|
||||
{ PIOC, PIO_PC28B_TIOA7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA7 }, // TIOA7
|
||||
{ PIOC, PIO_PC26B_TIOB6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB6 }, // TIOB6
|
||||
|
||||
// 5
|
||||
{ PIOC, PIO_PC25B_TIOA6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA6 }, // TIOA6
|
||||
{ PIOC, PIO_PC24B_PWML7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH7, NOT_ON_TIMER }, // PWML7
|
||||
{ PIOC, PIO_PC23B_PWML6, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH6, NOT_ON_TIMER }, // PWML6
|
||||
{ PIOC, PIO_PC22B_PWML5, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH5, NOT_ON_TIMER }, // PWML5
|
||||
{ PIOC, PIO_PC21B_PWML4, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH4, NOT_ON_TIMER }, // PWML4
|
||||
// 10
|
||||
{ PIOC, PIO_PC29B_TIOB7, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB7 }, // TIOB7
|
||||
{ PIOD, PIO_PD7B_TIOA8, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHA8 }, // TIOA8
|
||||
{ PIOD, PIO_PD8B_TIOB8, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC2_CHB8 }, // TIOB8
|
||||
|
||||
// 13 - AMBER LED
|
||||
{ PIOB, PIO_PB27B_TIOB0, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_TIMER), NO_ADC, NO_ADC, NOT_ON_PWM, TC0_CHB0 }, // TIOB0
|
||||
|
||||
// 14/15 - USART3 (Serial3)
|
||||
{ PIOD, PIO_PD4B_TXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD3
|
||||
{ PIOD, PIO_PD5B_RXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD3
|
||||
|
||||
// 16/17 - USART1 (Serial2)
|
||||
{ PIOA, PIO_PA13A_TXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD1
|
||||
{ PIOA, PIO_PA12A_RXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD1
|
||||
|
||||
// 18/19 - USART0 (Serial1)
|
||||
{ PIOA, PIO_PA11A_TXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TXD0
|
||||
{ PIOA, PIO_PA10A_RXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // RXD0
|
||||
|
||||
// 20/21 - TWI1
|
||||
{ PIOB, PIO_PB12A_TWD1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWD1 - SDA0
|
||||
{ PIOB, PIO_PB13A_TWCK1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWCK1 - SCL0
|
||||
|
||||
// 22
|
||||
{ PIOB, PIO_PB26, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 22
|
||||
{ PIOA, PIO_PA14, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 23
|
||||
{ PIOA, PIO_PA15, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 24
|
||||
{ PIOD, PIO_PD0, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 25
|
||||
|
||||
// 26
|
||||
{ PIOD, PIO_PD1, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 26
|
||||
{ PIOD, PIO_PD2, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 27
|
||||
{ PIOD, PIO_PD3, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 28
|
||||
{ PIOD, PIO_PD6, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 29
|
||||
|
||||
// 30
|
||||
{ PIOD, PIO_PD9, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 30
|
||||
{ PIOA, PIO_PA7, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 31
|
||||
{ PIOD, PIO_PD10, ID_PIOD, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 32
|
||||
{ PIOC, PIO_PC1, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 33
|
||||
|
||||
// 34
|
||||
{ PIOC, PIO_PC2, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 34
|
||||
{ PIOC, PIO_PC3, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 35
|
||||
{ PIOC, PIO_PC4, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 36
|
||||
{ PIOC, PIO_PC5, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 37
|
||||
|
||||
// 38
|
||||
{ PIOC, PIO_PC6, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 38
|
||||
{ PIOC, PIO_PC7, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 39
|
||||
{ PIOC, PIO_PC8, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 40
|
||||
{ PIOC, PIO_PC9, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 41
|
||||
|
||||
// 42
|
||||
{ PIOA, PIO_PA19, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 42
|
||||
{ PIOA, PIO_PA20, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 43
|
||||
{ PIOC, PIO_PC19, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 44
|
||||
{ PIOC, PIO_PC18, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 45
|
||||
|
||||
// 46
|
||||
{ PIOC, PIO_PC17, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 46
|
||||
{ PIOC, PIO_PC16, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 47
|
||||
{ PIOC, PIO_PC15, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 48
|
||||
{ PIOC, PIO_PC14, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 49
|
||||
|
||||
// 50
|
||||
{ PIOC, PIO_PC13, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 50
|
||||
{ PIOC, PIO_PC12, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 51
|
||||
{ PIOB, PIO_PB21, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 52
|
||||
{ PIOB, PIO_PB14, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 53
|
||||
|
||||
|
||||
// 54 .. 65 - Analog pins
|
||||
// ----------------------
|
||||
{ PIOA, PIO_PA16X1_AD7, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC0, ADC7, NOT_ON_PWM, NOT_ON_TIMER }, // AD0
|
||||
{ PIOA, PIO_PA24X1_AD6, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC1, ADC6, NOT_ON_PWM, NOT_ON_TIMER }, // AD1
|
||||
{ PIOA, PIO_PA23X1_AD5, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC2, ADC5, NOT_ON_PWM, NOT_ON_TIMER }, // AD2
|
||||
{ PIOA, PIO_PA22X1_AD4, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC3, ADC4, NOT_ON_PWM, NOT_ON_TIMER }, // AD3
|
||||
// 58
|
||||
{ PIOA, PIO_PA6X1_AD3, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC4, ADC3, NOT_ON_PWM, TC0_CHB2 }, // AD4
|
||||
{ PIOA, PIO_PA4X1_AD2, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC5, ADC2, NOT_ON_PWM, NOT_ON_TIMER }, // AD5
|
||||
{ PIOA, PIO_PA3X1_AD1, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC6, ADC1, NOT_ON_PWM, TC0_CHB1 }, // AD6
|
||||
{ PIOA, PIO_PA2X1_AD0, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC7, ADC0, NOT_ON_PWM, TC0_CHA1 }, // AD7
|
||||
// 62
|
||||
{ PIOB, PIO_PB17X1_AD10, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC8, ADC10, NOT_ON_PWM, NOT_ON_TIMER }, // AD8
|
||||
{ PIOB, PIO_PB18X1_AD11, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC9, ADC11, NOT_ON_PWM, NOT_ON_TIMER }, // AD9
|
||||
{ PIOB, PIO_PB19X1_AD12, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC10, ADC12, NOT_ON_PWM, NOT_ON_TIMER }, // AD10
|
||||
{ PIOB, PIO_PB20X1_AD13, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC11, ADC13, NOT_ON_PWM, NOT_ON_TIMER }, // AD11
|
||||
|
||||
// 66/67 - DAC0/DAC1
|
||||
{ PIOB, PIO_PB15X1_DAC0, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC12, DA0, NOT_ON_PWM, NOT_ON_TIMER }, // DAC0
|
||||
{ PIOB, PIO_PB16X1_DAC1, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC13, DA1, NOT_ON_PWM, NOT_ON_TIMER }, // DAC1
|
||||
|
||||
// 68/69 - CANRX0/CANTX0
|
||||
{ PIOA, PIO_PA1A_CANRX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, ADC14, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANRX
|
||||
{ PIOA, PIO_PA0A_CANTX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, ADC15, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANTX
|
||||
|
||||
// 70/71 - TWI0
|
||||
{ PIOA, PIO_PA17A_TWD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWD0 - SDA1
|
||||
{ PIOA, PIO_PA18A_TWCK0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // TWCK0 - SCL1
|
||||
|
||||
// 72/73 - LEDs
|
||||
{ PIOC, PIO_PC30, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // LED AMBER RXL
|
||||
{ PIOA, PIO_PA21, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // LED AMBER TXL
|
||||
|
||||
// 74/75/76 - SPI
|
||||
{ PIOA, PIO_PA25A_SPI0_MISO,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // MISO
|
||||
{ PIOA, PIO_PA26A_SPI0_MOSI,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // MOSI
|
||||
{ PIOA, PIO_PA27A_SPI0_SPCK,ID_PIOA,PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // SPCK
|
||||
|
||||
// 77 - SPI CS0
|
||||
{ PIOA, PIO_PA28A_SPI0_NPCS0,ID_PIOA,PIO_PERIPH_A,PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS0
|
||||
|
||||
// 78 - SPI CS3 (unconnected)
|
||||
{ PIOB, PIO_PB23B_SPI0_NPCS3,ID_PIOB,PIO_PERIPH_B,PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS3
|
||||
|
||||
// 79 .. 84 - "All pins" masks
|
||||
|
||||
// 79 - TWI0 all pins
|
||||
{ PIOA, PIO_PA17A_TWD0|PIO_PA18A_TWCK0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
// 80 - TWI1 all pins
|
||||
{ PIOB, PIO_PB12A_TWD1|PIO_PB13A_TWCK1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
// 81 - UART (Serial) all pins
|
||||
{ PIOA, PIO_PA8A_URXD|PIO_PA9A_UTXD, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
// 82 - USART0 (Serial1) all pins
|
||||
{ PIOA, PIO_PA11A_TXD0|PIO_PA10A_RXD0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
// 83 - USART1 (Serial2) all pins
|
||||
{ PIOA, PIO_PA13A_TXD1|PIO_PA12A_RXD1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
// 84 - USART3 (Serial3) all pins
|
||||
{ PIOD, PIO_PD4B_TXD3|PIO_PD5B_RXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
|
||||
// 85 - USB
|
||||
{ PIOB, PIO_PB11A_UOTGID, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL,NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ID
|
||||
// { PIOB, PIO_PB11A_UOTGID|PIO_PB10A_UOTGVBOF, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL,NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ID - VBOF
|
||||
// 86 - SPI CS2
|
||||
{ PIOB, PIO_PB21B_SPI0_NPCS2, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS2
|
||||
|
||||
// 87 - SPI CS1
|
||||
{ PIOA, PIO_PA29A_SPI0_NPCS1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS1
|
||||
|
||||
// 88/89 - CANRX1/CANTX1 (same physical pin for 66/53)
|
||||
{ PIOB, PIO_PB15A_CANRX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANRX1
|
||||
{ PIOB, PIO_PB14A_CANTX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // CANTX1
|
||||
|
||||
// 90 .. 91 - "All CAN pins" masks
|
||||
// 90 - CAN0 all pins
|
||||
{ PIOA, PIO_PA1A_CANRX0|PIO_PA0A_CANTX0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
// 91 - CAN1 all pins
|
||||
{ PIOB, PIO_PB15A_CANRX1|PIO_PB14A_CANTX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
|
||||
// 92 .. 99 placeholders, future-proofing.
|
||||
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
// 100 - 108 extra SAM3X8E pins, not wired on Due
|
||||
{ PIOA, PIO_PA5, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 100
|
||||
{ PIOC, PIO_PC27, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 101
|
||||
{ PIOA, PIO_PA0, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 102
|
||||
{ PIOA, PIO_PA1, ID_PIOA, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 103
|
||||
{ PIOC, PIO_PC11, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 104
|
||||
{ PIOC, PIO_PC8B_PWML3, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH3, NOT_ON_TIMER }, // PWM 105
|
||||
{ PIOC, PIO_PC2B_PWML0, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH0, NOT_ON_TIMER }, // PWM 106
|
||||
{ PIOC, PIO_PC6B_PWML2, ID_PIOC, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM), NO_ADC, NO_ADC, PWM_CH2, NOT_ON_TIMER }, //PWM 107
|
||||
{ PIOC, PIO_PC20, ID_PIOC, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, //PWM 108
|
||||
// 109 .. 114
|
||||
{ PIOA, PIO_PA20A_MCCDA, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN_HSMCI_MCCDA_GPIO 109
|
||||
{ PIOA, PIO_PA19A_MCCK, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN_HSMCI_MCCK_GPIO 110
|
||||
{ PIOA, PIO_PA21A_MCDA0, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN_HSMCI_MCDA0_GPIO 111
|
||||
{ PIOA, PIO_PA22A_MCDA1, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN_HSMCI_MCDA1_GPIO 112
|
||||
{ PIOA, PIO_PA23A_MCDA2, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN_HSMCI_MCDA2_GPIO 113
|
||||
{ PIOA, PIO_PA24A_MCDA3, ID_PIOA, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN_HSMCI_MCDA3_GPIO 114
|
||||
// 115 .. 124 - ETHERNET MAC
|
||||
{ PIOB, PIO_PB0A_ETXCK, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ETXCK 115
|
||||
{ PIOB, PIO_PB1A_ETXEN, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ETXEN 116
|
||||
{ PIOB, PIO_PB2A_ETX0, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ETX0 117
|
||||
{ PIOB, PIO_PB3A_ETX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ETX1 118
|
||||
{ PIOB, PIO_PB4A_ECRSDV, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ECRSDV 119
|
||||
{ PIOB, PIO_PB5A_ERX0, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ERX0 120
|
||||
{ PIOB, PIO_PB6A_ERX1, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ERX1 121
|
||||
{ PIOB, PIO_PB7A_ERXER, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ERXER 122
|
||||
{ PIOB, PIO_PB8A_EMDC, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // EMDC 123
|
||||
{ PIOB, PIO_PB9A_EMDIO, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // EMDIO 124
|
||||
// 125
|
||||
{ PIOB, PIO_PB24, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 125
|
||||
{ PIOB, PIO_PB21X1_AD14, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC0, ADC14, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 126 - PB21 with enabled ADC
|
||||
{ PIOB, PIO_PB13X1_AD9, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC0, ADC9, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 127 - PB13 with enabled ACD AD9
|
||||
{ PIOB, PIO_PB22, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 128 - PB22 E1 Enabled
|
||||
{ PIOB, PIO_PB10A_UOTGVBOF, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL,NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ID - VBOF 129
|
||||
|
||||
// END
|
||||
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }
|
||||
} ;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* UART objects
|
||||
*/
|
||||
RingBuffer rx_buffer1;
|
||||
RingBuffer tx_buffer1;
|
||||
|
||||
UARTClass Serial(UART, UART_IRQn, ID_UART, &rx_buffer1, &tx_buffer1);
|
||||
void serialEvent() __attribute__((weak));
|
||||
void serialEvent() { }
|
||||
|
||||
// IT handlers
|
||||
void UART_Handler(void)
|
||||
{
|
||||
Serial.IrqHandler();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/*
|
||||
* USART objects
|
||||
*/
|
||||
RingBuffer rx_buffer2;
|
||||
RingBuffer rx_buffer3;
|
||||
RingBuffer rx_buffer4;
|
||||
RingBuffer tx_buffer2;
|
||||
RingBuffer tx_buffer3;
|
||||
RingBuffer tx_buffer4;
|
||||
|
||||
USARTClass Serial1(USART0, USART0_IRQn, ID_USART0, &rx_buffer2, &tx_buffer2);
|
||||
void serialEvent1() __attribute__((weak));
|
||||
void serialEvent1() { }
|
||||
USARTClass Serial2(USART1, USART1_IRQn, ID_USART1, &rx_buffer3, &tx_buffer3);
|
||||
void serialEvent2() __attribute__((weak));
|
||||
void serialEvent2() { }
|
||||
USARTClass Serial3(USART3, USART3_IRQn, ID_USART3, &rx_buffer4, &tx_buffer4);
|
||||
void serialEvent3() __attribute__((weak));
|
||||
void serialEvent3() { }
|
||||
|
||||
// IT handlers
|
||||
void USART0_Handler(void)
|
||||
{
|
||||
Serial1.IrqHandler();
|
||||
}
|
||||
|
||||
void USART1_Handler(void)
|
||||
{
|
||||
Serial2.IrqHandler();
|
||||
}
|
||||
|
||||
void USART3_Handler(void)
|
||||
{
|
||||
Serial3.IrqHandler();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void serialEventRun(void)
|
||||
{
|
||||
if (Serial.available()) serialEvent();
|
||||
if (Serial1.available()) serialEvent1();
|
||||
if (Serial2.available()) serialEvent2();
|
||||
if (Serial3.available()) serialEvent3();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void __libc_init_array(void);
|
||||
|
||||
void init( void )
|
||||
{
|
||||
SystemInit();
|
||||
|
||||
// Set Systick to 1ms interval, common to all SAM3 variants
|
||||
if (SysTick_Config(SystemCoreClock / 1000))
|
||||
{
|
||||
// Capture error
|
||||
while (true);
|
||||
}
|
||||
|
||||
// Disable watchdog
|
||||
//WDT_Disable(WDT);
|
||||
// Initialize C library
|
||||
__libc_init_array();
|
||||
|
||||
// Disable pull-up on every pin
|
||||
for (unsigned i = 0; i < PINS_COUNT; i++)
|
||||
digitalWrite(i, LOW);
|
||||
|
||||
// Enable parallel access on PIO output data registers
|
||||
PIOA->PIO_OWER = 0xFFFFFFFF;
|
||||
PIOB->PIO_OWER = 0xFFFFFFFF;
|
||||
PIOC->PIO_OWER = 0xFFFFFFFF;
|
||||
PIOD->PIO_OWER = 0xFFFFFFFF;
|
||||
|
||||
// Initialize Serial port U(S)ART pins
|
||||
PIO_Configure(
|
||||
g_APinDescription[PINS_UART].pPort,
|
||||
g_APinDescription[PINS_UART].ulPinType,
|
||||
g_APinDescription[PINS_UART].ulPin,
|
||||
g_APinDescription[PINS_UART].ulPinConfiguration);
|
||||
digitalWrite(0, HIGH); // Enable pullup for RX0
|
||||
PIO_Configure(
|
||||
g_APinDescription[PINS_USART0].pPort,
|
||||
g_APinDescription[PINS_USART0].ulPinType,
|
||||
g_APinDescription[PINS_USART0].ulPin,
|
||||
g_APinDescription[PINS_USART0].ulPinConfiguration);
|
||||
PIO_Configure(
|
||||
g_APinDescription[PINS_USART1].pPort,
|
||||
g_APinDescription[PINS_USART1].ulPinType,
|
||||
g_APinDescription[PINS_USART1].ulPin,
|
||||
g_APinDescription[PINS_USART1].ulPinConfiguration);
|
||||
PIO_Configure(
|
||||
g_APinDescription[PINS_USART3].pPort,
|
||||
g_APinDescription[PINS_USART3].ulPinType,
|
||||
g_APinDescription[PINS_USART3].ulPin,
|
||||
g_APinDescription[PINS_USART3].ulPinConfiguration);
|
||||
|
||||
// Initialize USB pins
|
||||
PIO_Configure(
|
||||
g_APinDescription[PINS_USB].pPort,
|
||||
g_APinDescription[PINS_USB].ulPinType,
|
||||
g_APinDescription[PINS_USB].ulPin,
|
||||
g_APinDescription[PINS_USB].ulPinConfiguration);
|
||||
|
||||
// Initialize CAN pins
|
||||
PIO_Configure(
|
||||
g_APinDescription[PINS_CAN0].pPort,
|
||||
g_APinDescription[PINS_CAN0].ulPinType,
|
||||
g_APinDescription[PINS_CAN0].ulPin,
|
||||
g_APinDescription[PINS_CAN0].ulPinConfiguration);
|
||||
PIO_Configure(
|
||||
g_APinDescription[PINS_CAN1].pPort,
|
||||
g_APinDescription[PINS_CAN1].ulPinType,
|
||||
g_APinDescription[PINS_CAN1].ulPin,
|
||||
g_APinDescription[PINS_CAN1].ulPinConfiguration);
|
||||
|
||||
// Initialize Analog Controller
|
||||
pmc_enable_periph_clk(ID_ADC);
|
||||
adc_init(ADC, SystemCoreClock, ADC_FREQ_MAX, ADC_STARTUP_FAST);
|
||||
adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1);
|
||||
adc_configure_trigger(ADC, ADC_TRIG_SW, 0); // Disable hardware trigger.
|
||||
adc_disable_interrupt(ADC, 0xFFFFFFFF); // Disable all ADC interrupts.
|
||||
adc_disable_all_channel(ADC);
|
||||
|
||||
// Initialize analogOutput module
|
||||
analogOutputInit();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
@ -66,27 +66,16 @@ const uint16_t STRING_LANGUAGE[2] = {
|
|||
};
|
||||
|
||||
#ifndef USB_PRODUCT
|
||||
// Use a hardcoded product name if none is provided
|
||||
#if USB_PID == USB_PID_DUE
|
||||
#define USB_PRODUCT "Arduino Due"
|
||||
#else
|
||||
#define USB_PRODUCT "USB IO Board"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const uint8_t STRING_PRODUCT[] = USB_PRODUCT;
|
||||
|
||||
#if USB_VID == 0x2341
|
||||
# if defined(USB_MANUFACTURER)
|
||||
# undef USB_MANUFACTURER
|
||||
# endif
|
||||
# define USB_MANUFACTURER "Arduino LLC"
|
||||
#elif !defined(USB_MANUFACTURER)
|
||||
// Fall through to unknown if no manufacturer name was provided in a macro
|
||||
# define USB_MANUFACTURER "Unknown"
|
||||
#ifndef USB_MANUFACTURER
|
||||
#define USB_MANUFACTURER "Arduino LLC"
|
||||
#endif
|
||||
|
||||
const uint8_t STRING_MANUFACTURER[12] = USB_MANUFACTURER;
|
||||
const uint8_t STRING_MANUFACTURER[] = USB_MANUFACTURER;
|
||||
|
||||
#ifdef CDC_ENABLED
|
||||
#define DEVICE_CLASS 0x02
|
|
@ -268,10 +268,8 @@ extern const PinDescription g_APinDescription[]=
|
|||
// 84 - USART3 (Serial3) all pins
|
||||
{ PIOD, PIO_PD4B_TXD3|PIO_PD5B_RXD3, ID_PIOD, PIO_PERIPH_B, PIO_DEFAULT, (PIN_ATTR_DIGITAL|PIN_ATTR_COMBO), NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER },
|
||||
|
||||
// 85 - USB
|
||||
//For Davinci only
|
||||
{ PIOB, PIO_PB11A_UOTGID, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL,NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ID
|
||||
// { PIOB, PIO_PB11A_UOTGID|PIO_PB10A_UOTGVBOF, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL,NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ID - VBOF
|
||||
// 85 - USB
|
||||
{ PIOB, PIO_PB11A_UOTGID|PIO_PB10A_UOTGVBOF, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL,NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ID - VBOF
|
||||
// 86 - SPI CS2
|
||||
{ PIOB, PIO_PB21B_SPI0_NPCS2, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // NPCS2
|
||||
|
||||
|
@ -330,7 +328,7 @@ extern const PinDescription g_APinDescription[]=
|
|||
{ PIOB, PIO_PB21X1_AD14, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC0, ADC14, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 126 - PB21 with enabled ADC
|
||||
{ PIOB, PIO_PB13X1_AD9, ID_PIOB, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC0, ADC9, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 127 - PB13 with enabled ACD AD9
|
||||
{ PIOB, PIO_PB22, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 128 - PB22 E1 Enabled
|
||||
{ PIOB, PIO_PB10A_UOTGVBOF, ID_PIOB, PIO_PERIPH_A, PIO_DEFAULT, PIN_ATTR_DIGITAL,NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ID - VBOF 129
|
||||
{ PIOB, PIO_PB10B_A18, ID_PIOB, PIO_PERIPH_B, PIO_DEFAULT, PIN_ATTR_DIGITAL,NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // ID 129
|
||||
|
||||
// END
|
||||
{ NULL, 0, 0, PIO_NOT_A_PIN, PIO_DEFAULT, 0, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }
|
|
@ -0,0 +1,288 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# This file is part of the Horus Project
|
||||
|
||||
__author__ = 'Jesús Arroyo Torrens <jesus.arroyo@bq.com>'
|
||||
__copyright__ = 'Copyright (C) 2014-2016 Mundo Reader S.L.'
|
||||
__license__ = 'GNU General Public License v2 http://www.gnu.org/licenses/gpl2.html'
|
||||
|
||||
import time
|
||||
import glob
|
||||
import serial
|
||||
import threading
|
||||
import platform
|
||||
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
system = platform.system()
|
||||
|
||||
|
||||
class WrongFirmware(Exception):
|
||||
|
||||
def __init__(self):
|
||||
Exception.__init__(self, "Wrong Firmware")
|
||||
|
||||
|
||||
class BoardNotConnected(Exception):
|
||||
|
||||
def __init__(self):
|
||||
Exception.__init__(self, "Board Not Connected")
|
||||
|
||||
|
||||
class OldFirmware(Exception):
|
||||
|
||||
def __init__(self):
|
||||
Exception.__init__(self, "Old Firmware")
|
||||
|
||||
|
||||
class Board(object):
|
||||
|
||||
"""Board class. For accessing to the scanner board
|
||||
Mofified for Davinci AiO support
|
||||
Gcode commands:
|
||||
|
||||
G201 Fnnn : feed rate
|
||||
G201 Xnnn : move motor in mm
|
||||
G201 Ennn : move motor in deg
|
||||
G50 : reset origin position
|
||||
M17 : motor_disable
|
||||
M18 : motor_enable
|
||||
M70 Tn : switch off laser n, 0 index based
|
||||
M71 Tn : switch on laser n, 0 index based
|
||||
|
||||
M60 Tn : read ldr sensor
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, parent=None, serial_name='/dev/ttyUSB0', baud_rate=115200):
|
||||
self.parent = parent
|
||||
self.serial_name = serial_name
|
||||
self.baud_rate = baud_rate
|
||||
self.unplug_callback = None
|
||||
|
||||
self._serial_port = None
|
||||
self._is_connected = False
|
||||
self._motor_enabled = False
|
||||
self._motor_position = 0
|
||||
self._motor_speed = 0
|
||||
self._motor_acceleration = 0
|
||||
self._motor_direction = 1
|
||||
self._laser_number = 2
|
||||
self._laser_enabled = self._laser_number * [False]
|
||||
self._tries = 0 # Check if command fails
|
||||
|
||||
def connect(self):
|
||||
"""Open serial port and perform handshake"""
|
||||
logger.info("Connecting board {0} {1}".format(self.serial_name, self.baud_rate))
|
||||
self._is_connected = False
|
||||
try:
|
||||
self._serial_port = serial.Serial(self.serial_name, self.baud_rate, timeout=2)
|
||||
if self._serial_port.isOpen():
|
||||
#self._reset() # Force Reset and flush
|
||||
# version = self._serial_port.readline()
|
||||
# if "Horus 0.1 ['$' for help]" in version:
|
||||
# raise OldFirmware()
|
||||
# elif "Horus 0.2 ['$' for help]" in version:
|
||||
self.motor_speed(1)
|
||||
self._serial_port.timeout = 0.05
|
||||
self._is_connected = True
|
||||
# Set current position as origin
|
||||
self.motor_reset_origin()
|
||||
logger.info(" Done")
|
||||
#else:
|
||||
# raise WrongFirmware()
|
||||
else:
|
||||
raise BoardNotConnected()
|
||||
except Exception as exception:
|
||||
logger.error("Error opening the port {0}\n".format(self.serial_name))
|
||||
self._serial_port = None
|
||||
raise exception
|
||||
|
||||
def disconnect(self):
|
||||
"""Close serial port"""
|
||||
if self._is_connected:
|
||||
logger.info("Disconnecting board {0}".format(self.serial_name))
|
||||
try:
|
||||
if self._serial_port is not None:
|
||||
self.lasers_off()
|
||||
self.motor_disable()
|
||||
self._is_connected = False
|
||||
self._serial_port.close()
|
||||
del self._serial_port
|
||||
except serial.SerialException:
|
||||
logger.error("Error closing the port {0}\n".format(self.serial_name))
|
||||
logger.info(" Done")
|
||||
|
||||
def set_unplug_callback(self, value):
|
||||
self.unplug_callback = value
|
||||
|
||||
def motor_invert(self, value):
|
||||
if value:
|
||||
self._motor_direction = -1
|
||||
else:
|
||||
self._motor_direction = +1
|
||||
|
||||
def motor_speed(self, value):
|
||||
if self._is_connected:
|
||||
if self._motor_speed != value:
|
||||
self._motor_speed = value
|
||||
#Davici Specific
|
||||
self._send_command("G201 F{0}".format(value))
|
||||
|
||||
def motor_acceleration(self, value):
|
||||
if self._is_connected:
|
||||
if self._motor_acceleration != value:
|
||||
self._motor_acceleration = value
|
||||
#Davinci Specific
|
||||
#self._send_command("$120={0}".format(value))
|
||||
|
||||
def motor_enable(self):
|
||||
if self._is_connected:
|
||||
if not self._motor_enabled:
|
||||
self._motor_enabled = True
|
||||
# Save current speed value
|
||||
speed = self._motor_speed
|
||||
self.motor_speed(1)
|
||||
# Enable stepper motor
|
||||
self._send_command("M17")
|
||||
time.sleep(1)
|
||||
# Restore speed value
|
||||
self.motor_speed(speed)
|
||||
|
||||
def motor_disable(self):
|
||||
if self._is_connected:
|
||||
if self._motor_enabled:
|
||||
self._motor_enabled = False
|
||||
self._send_command("M18")
|
||||
|
||||
def motor_reset_origin(self):
|
||||
if self._is_connected:
|
||||
self._send_command("G50")
|
||||
self._motor_position = 0
|
||||
|
||||
def motor_move(self, step=0, nonblocking=False, callback=None):
|
||||
if self._is_connected:
|
||||
self._motor_position += step * self._motor_direction
|
||||
#Davici Specific
|
||||
self.send_command("G201 E{0}".format(self._motor_position), nonblocking, callback)
|
||||
|
||||
def laser_on(self, index):
|
||||
if self._is_connected:
|
||||
if not self._laser_enabled[index]:
|
||||
self._laser_enabled[index] = True
|
||||
#Davici Specific
|
||||
if index == 0:
|
||||
strindex="1"
|
||||
else :
|
||||
strindex="0"
|
||||
self._send_command("M71 T" + strindex)
|
||||
|
||||
def laser_off(self, index):
|
||||
if self._is_connected:
|
||||
if self._laser_enabled[index]:
|
||||
self._laser_enabled[index] = False
|
||||
#Davici Specific
|
||||
if index == 0:
|
||||
strindex="1"
|
||||
else :
|
||||
strindex="0"
|
||||
self._send_command("M70 T" + strindex)
|
||||
|
||||
def lasers_on(self):
|
||||
for i in xrange(self._laser_number):
|
||||
self.laser_on(i)
|
||||
|
||||
def lasers_off(self):
|
||||
for i in xrange(self._laser_number):
|
||||
self.laser_off(i)
|
||||
|
||||
def ldr_sensor(self, pin):
|
||||
value = self._send_command("M60 T" + pin, read_lines=True).split("\n")[0]
|
||||
try:
|
||||
return int(value)
|
||||
except ValueError:
|
||||
return 0
|
||||
|
||||
def send_command(self, req, nonblocking=False, callback=None, read_lines=False):
|
||||
if nonblocking:
|
||||
threading.Thread(target=self._send_command,
|
||||
args=(req, callback, read_lines)).start()
|
||||
else:
|
||||
self._send_command(req, callback, read_lines)
|
||||
|
||||
def _send_command(self, req, callback=None, read_lines=False):
|
||||
"""Sends the request and returns the response"""
|
||||
ret = ''
|
||||
logger.debug(req)
|
||||
if self._is_connected and req != '':
|
||||
if self._serial_port is not None and self._serial_port.isOpen():
|
||||
try:
|
||||
self._serial_port.flushInput()
|
||||
self._serial_port.flushOutput()
|
||||
self._serial_port.write(req + "\r\n")
|
||||
while req != '~' and req != '!' and ret == '':
|
||||
ret = self.read(read_lines)
|
||||
time.sleep(0.01)
|
||||
self._success()
|
||||
except:
|
||||
if hasattr(self, '_serial_port'):
|
||||
if callback is not None:
|
||||
callback(ret)
|
||||
self._fail()
|
||||
if callback is not None:
|
||||
callback(ret)
|
||||
return ret
|
||||
|
||||
def read(self, read_lines=False):
|
||||
if read_lines:
|
||||
return ''.join(self._serial_port.readlines())
|
||||
else:
|
||||
return ''.join(self._serial_port.readline())
|
||||
|
||||
def _success(self):
|
||||
self._tries = 0
|
||||
|
||||
def _fail(self):
|
||||
if self._is_connected:
|
||||
logger.debug("Board fail")
|
||||
self._tries += 1
|
||||
if self._tries >= 3:
|
||||
self._tries = 0
|
||||
if self.unplug_callback is not None and \
|
||||
self.parent is not None and \
|
||||
not self.parent.unplugged:
|
||||
self.parent.unplugged = True
|
||||
self.unplug_callback()
|
||||
|
||||
def _reset(self):
|
||||
self._serial_port.flushInput()
|
||||
self._serial_port.flushOutput()
|
||||
self._serial_port.write("\x18\r\n") # Ctrl-x
|
||||
self._serial_port.readline()
|
||||
|
||||
def get_serial_list(self):
|
||||
"""Obtain list of serial devices"""
|
||||
baselist = []
|
||||
if system == 'Windows':
|
||||
import _winreg
|
||||
try:
|
||||
key = _winreg.OpenKey(
|
||||
_winreg.HKEY_LOCAL_MACHINE, "HARDWARE\\DEVICEMAP\\SERIALCOMM")
|
||||
i = 0
|
||||
while True:
|
||||
try:
|
||||
values = _winreg.EnumValue(key, i)
|
||||
except:
|
||||
return baselist
|
||||
if 'USBSER' in values[0] or \
|
||||
'VCP' in values[0] or \
|
||||
'\Device\Serial' in values[0]:
|
||||
baselist.append(values[1])
|
||||
i += 1
|
||||
except:
|
||||
return baselist
|
||||
else:
|
||||
for device in ['/dev/ttyACM*', '/dev/ttyUSB*', '/dev/tty.usb*', '/dev/tty.wchusb*',
|
||||
'/dev/cu.*', '/dev/rfcomm*']:
|
||||
baselist = baselist + glob.glob(device)
|
||||
return baselist
|
|
@ -0,0 +1,773 @@
|
|||
|
||||
/*
|
||||
More and more printers now have automatic bed leveling using an ever increasing variety of methods.
|
||||
This makes the leveling routine one of the most complex parts of the firmware and there is not one
|
||||
way to level but hundreds of combinations.
|
||||
|
||||
First you should decide on the correction method. Once we know how our bed is tilted we want to
|
||||
remove that. This correction is defined by BED_CORRECTION_METHOD and allows the following values:
|
||||
BED_CORRECTION_METHOD 0
|
||||
Use a rotation matrix. This will make z axis go up/down while moving in x/y direction to compensate
|
||||
the tilt. For multiple extruders make sure the height match the tilt of the bed or one will scratch.
|
||||
|
||||
BED_CORRECTION_METHOD 1
|
||||
Motorized correction. This method needs a bed that is fixed on 3 points from which 2 have a motor
|
||||
to change the height. The positions are defined by
|
||||
BED_MOTOR_1_X, BED_MOTOR_1_Y, BED_MOTOR_2_X, BED_MOTOR_2_Y, BED_MOTOR_3_X, BED_MOTOR_3_Y
|
||||
Motor 2 and 3 are the one driven by motor driver 0 and 1. These can be extra motors like Felix Pro 1
|
||||
uses them or a system with 3 z axis where motors can be controlled individually like the Sparkcube
|
||||
does.
|
||||
|
||||
Next we have to distinguish several methods of z probing sensors. Each have their own advantages and
|
||||
disadvantages. First the z probe has a position when activated and that position is defined by
|
||||
#define Z_PROBE_X_OFFSET 0
|
||||
#define Z_PROBE_Y_OFFSET 0
|
||||
This is needed since we need to know where we measure the height when the z probe triggers. When
|
||||
probing is activated you will see a move to make probe go over current extruder position. The
|
||||
position can be changed in eeprom later on.
|
||||
|
||||
Some probes need to be activated/deactivated so we can use them. This is defined in the scripts
|
||||
#define Z_PROBE_START_SCRIPT ""
|
||||
#define Z_PROBE_FINISHED_SCRIPT ""
|
||||
|
||||
Now when we probe we want to know the distance of the extruder to the bed. This is defined by
|
||||
#define Z_PROBE_HEIGHT 4
|
||||
The 4 means that when we trigger the distance of the nozzle tip is 4mm. If your switch tends
|
||||
to return different points you might repeat a measured point and use the average height:
|
||||
#define Z_PROBE_SWITCHING_DISTANCE 1
|
||||
#define Z_PROBE_REPETITIONS 5
|
||||
Switching distance is the z raise needed to turn back a signal reliably to off. Inductive sensors
|
||||
need only a bit while mechanical switches may require a bit more.
|
||||
|
||||
Next thing to consider is the force for switching. Some beds use a cantilever design and pushing on
|
||||
the outside easily bends the bed. If your sensor needs some force to trigger you add the error of
|
||||
bending. For this reason you might add a bending correction. Currently you define
|
||||
#define BENDING_CORRECTION_A 0
|
||||
#define BENDING_CORRECTION_B 0
|
||||
#define BENDING_CORRECTION_C 0
|
||||
which are the deflections at the 3 z probe points. For all other possible measurements these values
|
||||
get interpolated. You can modify the values later on in eeprom. For force less sensors set them to 0.
|
||||
|
||||
Next thing is endstop handling. Without bed leveling you normally home to minimum position for x,y and z.
|
||||
With bed leveling this is not that easy any more. Since we do bed leveling we already assume the bed is
|
||||
not leveled for x/y moves. So without correction we would hit the bed for different x/y positions at
|
||||
different heights. As a result we have no real minimum position. That makes a z min endstop quite useless.
|
||||
There is an exception to this. If your nozzle triggers z min or if a inductive sensor would trigger at a given
|
||||
position we could use that signal. With nozzle triggers you need to be careful as a drop of filament
|
||||
would change the height. The other problem is that while homing the auto leveling is not used. So
|
||||
the only position would be if the z min sensor is directly over the 0,0 coordinate which is the rotation point
|
||||
if we have matrix based correction. For motor based correction this will work everywhere correctly.
|
||||
|
||||
So the only useful position for a z endstop is z max position. Apart from not having the bed tilt problem it
|
||||
also allows homing with a full bed so you can continue an aborted print with some gcode tweaking. With z max
|
||||
homing we adjust the error by simply changing the max. z height. One thing you need to remember is setting
|
||||
#define ENDSTOP_Z_BACK_ON_HOME 4
|
||||
so we release the z max endstop. This is very important if we move xy at z max. Auto leveling might want to
|
||||
increase z and the endstop might prevent it causing wrong position and a head crash if we later go down.
|
||||
The value should be larger then the maximum expected tilt.
|
||||
|
||||
Now it is time to define how we measure the bed rotation. Here again we have several methods to choose.
|
||||
All methods need at least 3 points to define the bed rotation correctly. The quality we get comes
|
||||
from the selection of the right points and method.
|
||||
|
||||
BED_LEVELING_METHOD 0
|
||||
This method measures at the 3 probe points and creates a plane through these points. If you have
|
||||
a really planar bed this gives the optimum result. The 3 points must not be in one line and have
|
||||
a long distance to increase numerical stability.
|
||||
|
||||
BED_LEVELING_METHOD 1
|
||||
This measures a grid. Probe point 1 is the origin and points 2 and 3 span a grid. We measure
|
||||
BED_LEVELING_GRID_SIZE points in each direction and compute a regression plane through all
|
||||
points. This gives a good overall plane if you have small bumps measuring inaccuracies.
|
||||
|
||||
BED_LEVELING_METHOD 2
|
||||
Bending correcting 4 point measurement. This is for cantilevered beds that have the rotation axis
|
||||
not at the side but inside the bed. Here we can assume no bending on the axis and a symmetric
|
||||
bending to both sides of the axis. So probe points 2 and 3 build the symmetric axis and
|
||||
point 1 is mirrored to 1m across the axis. Using the symmetry we then remove the bending
|
||||
from 1 and use that as plane.
|
||||
|
||||
By now the leveling process is finished. All errors that remain are measuring errors and bumps on
|
||||
the bed it self. For deltas you can enable distortion correction to follow the bumps.
|
||||
|
||||
There are 2 ways to consider a changing bed coating, which are defined by Z_PROBE_Z_OFFSET_MODE.
|
||||
Z_PROBE_Z_OFFSET_MODE = 0 means we measure the surface of the bed below any coating. This is e.g.
|
||||
the case with inductive sensors where we put BuildTak on top. In that case we can set Z_PROBE_Z_OFFSET
|
||||
to the thickness of BuildTak to compensate. If we later change the coating, we only change Z_PROBE_Z_OFFSET
|
||||
to new coating thickness.
|
||||
|
||||
Z_PROBE_Z_OFFSET_MODE = 1 means we measure the surface of the coating, e.g. because we have a mechanical switch.
|
||||
In that case we add Z_PROBE_Z_OFFSET for the measured height to compensate for correct distance to bed surface.
|
||||
|
||||
In homing to max we reduce z length by Z_PROBE_Z_OFFSET to get a correct height.
|
||||
In homing to z min we assume z endstop is bed level so we move up Z_PROBE_Z_OFFSET after endstop is hit. This
|
||||
requires the extruder to bend the coating thickness without harm!
|
||||
*/
|
||||
|
||||
#include "Repetier.h"
|
||||
|
||||
#ifndef BED_LEVELING_METHOD
|
||||
#define BED_LEVELING_METHOD 0
|
||||
#endif
|
||||
|
||||
#ifndef BED_CORRECTION_METHOD
|
||||
#define BED_CORRECTION_METHOD 0
|
||||
#endif
|
||||
|
||||
#ifndef BED_LEVELING_GRID_SIZE
|
||||
#define BED_LEVELING_GRID_SIZE 5
|
||||
#endif
|
||||
|
||||
#ifndef BED_LEVELING_REPETITIONS
|
||||
#define BED_LEVELING_REPETITIONS 1
|
||||
#endif
|
||||
|
||||
|
||||
class PlaneBuilder {
|
||||
float sum_xx,sum_xy,sum_yy,sum_x,sum_y,sum_xz,sum_yz,sum_z,n;
|
||||
public:
|
||||
PlaneBuilder() {
|
||||
reset();
|
||||
}
|
||||
void reset() {
|
||||
sum_xx = sum_xy = sum_yy = sum_x = sum_y = sum_xz = sum_yz = sum_z = n = 0;
|
||||
}
|
||||
void addPoint(float x,float y,float z) {
|
||||
n++;
|
||||
sum_xx += x * x;
|
||||
sum_xy += x * y;
|
||||
sum_yy += y * y;
|
||||
sum_x += x;
|
||||
sum_y += y;
|
||||
sum_xz += x * z;
|
||||
sum_yz += y * z;
|
||||
sum_z += z;
|
||||
}
|
||||
void createPlane(Plane &plane,bool silent=false) {
|
||||
float det = (sum_x * (sum_xy * sum_y - sum_x * sum_yy) + sum_xx * (n * sum_yy - sum_y * sum_y) + sum_xy * (sum_x * sum_y - n * sum_xy));
|
||||
plane.a = ((sum_xy * sum_y - sum_x * sum_yy) * sum_z + (sum_x * sum_y - n * sum_xy) * sum_yz + sum_xz * (n * sum_yy - sum_y * sum_y)) / det;
|
||||
plane.b = ((sum_x * sum_xy - sum_xx * sum_y) * sum_z + (n * sum_xx - sum_x * sum_x) * sum_yz + sum_xz * (sum_x * sum_y - n * sum_xy)) / det;
|
||||
plane.c = ((sum_xx * sum_yy - sum_xy * sum_xy) * sum_z + (sum_x * sum_xy - sum_xx * sum_y) * sum_yz + sum_xz * (sum_xy * sum_y - sum_x * sum_yy)) / det;
|
||||
if(!silent) {
|
||||
Com::printF(PSTR("plane: a = "),plane.a,4);
|
||||
Com::printF(PSTR(" b = "),plane.b,4);
|
||||
Com::printFLN(PSTR(" c = "),plane.c,4);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#if FEATURE_AUTOLEVEL && FEATURE_Z_PROBE
|
||||
|
||||
bool measureAutolevelPlane(Plane &plane) {
|
||||
PlaneBuilder builder;
|
||||
builder.reset();
|
||||
#if BED_LEVELING_METHOD == 0 // 3 point
|
||||
float h;
|
||||
Printer::moveTo(EEPROM::zProbeX1(),EEPROM::zProbeY1(),IGNORE_COORDINATE,IGNORE_COORDINATE,EEPROM::zProbeXYSpeed());
|
||||
h = Printer::runZProbe(false,false);
|
||||
if(h == ILLEGAL_Z_PROBE)
|
||||
{
|
||||
//Davinci Specific
|
||||
Printer::Z_probe[0]=-2000;
|
||||
Printer::zprobe_ok = false;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Printer::Z_probe[0]=h;
|
||||
}
|
||||
uid.refreshPage();
|
||||
builder.addPoint(EEPROM::zProbeX1(),EEPROM::zProbeY1(),h);
|
||||
Printer::moveTo(EEPROM::zProbeX2(),EEPROM::zProbeY2(),IGNORE_COORDINATE,IGNORE_COORDINATE,EEPROM::zProbeXYSpeed());
|
||||
h = Printer::runZProbe(false,false);
|
||||
if(h == ILLEGAL_Z_PROBE)
|
||||
{
|
||||
//Davinci Specific
|
||||
Printer::Z_probe[1]=-2000;
|
||||
Printer::zprobe_ok = false;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Printer::Z_probe[1]=h;
|
||||
}
|
||||
uid.refreshPage();
|
||||
builder.addPoint(EEPROM::zProbeX2(),EEPROM::zProbeY2(),h);
|
||||
Printer::moveTo(EEPROM::zProbeX3(),EEPROM::zProbeY3(),IGNORE_COORDINATE,IGNORE_COORDINATE,EEPROM::zProbeXYSpeed());
|
||||
h = Printer::runZProbe(false,false);
|
||||
if(h == ILLEGAL_Z_PROBE)
|
||||
{
|
||||
//Davinci Specific
|
||||
Printer::Z_probe[2]=-2000;
|
||||
Printer::zprobe_ok = false;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Printer::Z_probe[2]=h;
|
||||
}
|
||||
uid.refreshPage();
|
||||
builder.addPoint(EEPROM::zProbeX3(),EEPROM::zProbeY3(),h);
|
||||
#elif BED_LEVELING_METHOD == 1 // linear regression
|
||||
float delta = 1.0 / (BED_LEVELING_GRID_SIZE - 1);
|
||||
float ox = EEPROM::zProbeX1();
|
||||
float oy = EEPROM::zProbeY1();
|
||||
float ax = delta * (EEPROM::zProbeX2() - EEPROM::zProbeX1());
|
||||
float ay = delta * (EEPROM::zProbeY2() - EEPROM::zProbeY1());
|
||||
float bx = delta * (EEPROM::zProbeX3() - EEPROM::zProbeX1());
|
||||
float by = delta * (EEPROM::zProbeY3() - EEPROM::zProbeY1());
|
||||
for(int ix = 0; ix < BED_LEVELING_GRID_SIZE; ix++) {
|
||||
for(int iy = 0; iy < BED_LEVELING_GRID_SIZE; iy++) {
|
||||
float px = ox + static_cast<float>(ix) * ax + static_cast<float>(iy) * bx;
|
||||
float py = oy + static_cast<float>(ix) * ay + static_cast<float>(iy) * by;
|
||||
Printer::moveTo(px,py,IGNORE_COORDINATE,IGNORE_COORDINATE,EEPROM::zProbeXYSpeed());
|
||||
float h = Printer::runZProbe(false,false);
|
||||
if(h == ILLEGAL_Z_PROBE)
|
||||
return false;
|
||||
builder.addPoint(px,py,h);
|
||||
}
|
||||
}
|
||||
|
||||
#elif BED_LEVELING_METHOD == 2 // 4 point symmetric
|
||||
float h1,h2,h3,h4;
|
||||
float apx = EEPROM::zProbeX1() - EEPROM::zProbeX2();
|
||||
float apy = EEPROM::zProbeY1() - EEPROM::zProbeY2();
|
||||
float abx = EEPROM::zProbeX3() - EEPROM::zProbeX2();
|
||||
float aby = EEPROM::zProbeY3() - EEPROM::zProbeY2();
|
||||
float ab2 = abx * abx + aby * aby;
|
||||
float abap = apx * abx + apy * aby;
|
||||
float t = abap / ab2;
|
||||
float xx = EEPROM::zProbeX2() + t * abx;
|
||||
float xy = EEPROM::zProbeY2() + t * aby;
|
||||
float x1Mirror = EEPROM::zProbeX1() + 2.0 * (xx - EEPROM::zProbeX1());
|
||||
float y1Mirror = EEPROM::zProbeY1() + 2.0 * (xy - EEPROM::zProbeY1());
|
||||
Printer::moveTo(EEPROM::zProbeX1(),EEPROM::zProbeY1(),IGNORE_COORDINATE,IGNORE_COORDINATE,EEPROM::zProbeXYSpeed());
|
||||
h1 = Printer::runZProbe(false,false);
|
||||
if(h1 == ILLEGAL_Z_PROBE)
|
||||
return false;
|
||||
Printer::moveTo(EEPROM::zProbeX2(),EEPROM::zProbeY2(),IGNORE_COORDINATE,IGNORE_COORDINATE,EEPROM::zProbeXYSpeed());
|
||||
h2 = Printer::runZProbe(false,false);
|
||||
if(h2 == ILLEGAL_Z_PROBE)
|
||||
return false;
|
||||
Printer::moveTo(EEPROM::zProbeX3(),EEPROM::zProbeY3(),IGNORE_COORDINATE,IGNORE_COORDINATE,EEPROM::zProbeXYSpeed());
|
||||
h3 = Printer::runZProbe(false,false);
|
||||
if(h3 == ILLEGAL_Z_PROBE)
|
||||
return false;
|
||||
Printer::moveTo(x1Mirror,y1Mirror,IGNORE_COORDINATE,IGNORE_COORDINATE,EEPROM::zProbeXYSpeed());
|
||||
h4 = Printer::runZProbe(false,false);
|
||||
if(h4 == ILLEGAL_Z_PROBE)
|
||||
return false;
|
||||
t = h2 + (h3 - h2) * t; // theoretical height for crossing point for symmetric axis
|
||||
h1 = t - (h4 - h1) * 0.5; // remove bending part
|
||||
builder.addPoint(EEPROM::zProbeX1(), EEPROM::zProbeY1(), h1);
|
||||
builder.addPoint(EEPROM::zProbeX2(), EEPROM::zProbeY2(), h2);
|
||||
builder.addPoint(EEPROM::zProbeX3(), EEPROM::zProbeY3(), h3);
|
||||
#else
|
||||
#error Unknown bed leveling method
|
||||
#endif
|
||||
builder.createPlane(plane,false);
|
||||
return true;
|
||||
}
|
||||
|
||||
void correctAutolevel(GCode *code,Plane &plane) {
|
||||
#if BED_CORRECTION_METHOD == 0 // rotation matrix
|
||||
//Printer::buildTransformationMatrix(plane.z(EEPROM::zProbeX1(),EEPROM::zProbeY1()),plane.z(EEPROM::zProbeX2(),EEPROM::zProbeY2()),plane.z(EEPROM::zProbeX3(),EEPROM::zProbeY3()));
|
||||
Printer::buildTransformationMatrix(plane);
|
||||
#elif BED_CORRECTION_METHOD == 1 // motorized correction
|
||||
#if !defined(NUM_MOTOR_DRIVERS) || NUM_MOTOR_DRIVERS < 2
|
||||
#error You need to define 2 motors for motorized bed correction
|
||||
#endif
|
||||
Commands::waitUntilEndOfAllMoves(); // move steppers might be leveling steppers as well !
|
||||
float h1 = plane.z(BED_MOTOR_1_X,BED_MOTOR_1_Y);
|
||||
float h2 = plane.z(BED_MOTOR_2_X,BED_MOTOR_2_Y);
|
||||
float h3 = plane.z(BED_MOTOR_3_X,BED_MOTOR_3_Y);
|
||||
// h1 is reference heights, h2 => motor 0, h3 => motor 1
|
||||
h2 -= h1;
|
||||
h3 -= h1;
|
||||
#if defined(LIMIT_MOTORIZED_CORRECTION)
|
||||
if(h2 < -LIMIT_MOTORIZED_CORRECTION) h2 = -LIMIT_MOTORIZED_CORRECTION;
|
||||
if(h2 > LIMIT_MOTORIZED_CORRECTION) h2 = LIMIT_MOTORIZED_CORRECTION;
|
||||
if(h3 < -LIMIT_MOTORIZED_CORRECTION) h3 = -LIMIT_MOTORIZED_CORRECTION;
|
||||
if(h3 > LIMIT_MOTORIZED_CORRECTION) h3 = LIMIT_MOTORIZED_CORRECTION;
|
||||
#endif
|
||||
MotorDriverInterface *motor2 = getMotorDriver(0);
|
||||
MotorDriverInterface *motor3 = getMotorDriver(1);
|
||||
motor2->setCurrentAs(0);
|
||||
motor3->setCurrentAs(0);
|
||||
motor2->gotoPosition(h2);
|
||||
motor3->gotoPosition(h3);
|
||||
motor2->disable();
|
||||
motor3->disable(); // now bed is even
|
||||
Printer::currentPositionSteps[Z_AXIS] = h1 * Printer::axisStepsPerMM[Z_AXIS];
|
||||
#else
|
||||
#error Unknown bed correction method set
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
Implementation of the G32 command
|
||||
G32 S<0..2> - Autolevel print bed. S = 1 measure zLength, S = 2 Measure and store new zLength
|
||||
S = 0 : Do not update length - use this if you have not homed before or you mess up zlength!
|
||||
S = 1 : Measure zLength so homing works
|
||||
S = 2 : Like s = 1 plus store results in EEPROM for next connection.
|
||||
*/
|
||||
bool runBedLeveling(GCode *com) {
|
||||
float h1,h2,h3,hc,oldFeedrate = Printer::feedrate;
|
||||
int s = com->hasS() ? com->S : -1;
|
||||
#if DISTORTION_CORRECTION
|
||||
bool distEnabled = Printer::distortion.isEnabled();
|
||||
Printer::distortion.disable(false); // if level has changed, distortion is also invalid
|
||||
#endif
|
||||
Printer::setAutolevelActive(false); // iterate
|
||||
Printer::resetTransformationMatrix(true); // in case we switch from matrix to motorized!
|
||||
#if DRIVE_SYSTEM == DELTA
|
||||
// It is not possible to go to the edges at the top, also users try
|
||||
// it often and wonder why the coordinate system is then wrong.
|
||||
// For that reason we ensure a correct behavior by code.
|
||||
Printer::homeAxis(true, true, true);
|
||||
Printer::moveTo(IGNORE_COORDINATE, IGNORE_COORDINATE, EEPROM::zProbeBedDistance() + EEPROM::zProbeHeight(), IGNORE_COORDINATE, Printer::homingFeedrate[Z_AXIS]);
|
||||
#endif
|
||||
Printer::startProbing(true);
|
||||
//GCode::executeFString(Com::tZProbeStartScript);
|
||||
Printer::coordinateOffset[X_AXIS] = Printer::coordinateOffset[Y_AXIS] = Printer::coordinateOffset[Z_AXIS] = 0;
|
||||
Plane plane;
|
||||
#if BED_CORRECTION_METHOD == 1
|
||||
for(int r = 0; r < BED_LEVELING_REPETITIONS; r++) {
|
||||
#if DRIVE_SYSTEM == DELTA
|
||||
if(r > 0) {
|
||||
Printer::finishProbing();
|
||||
Printer::homeAxis(true, true, true);
|
||||
Printer::moveTo(IGNORE_COORDINATE, IGNORE_COORDINATE, EEPROM::zProbeBedDistance() + EEPROM::zProbeHeight(), IGNORE_COORDINATE, Printer::homingFeedrate[Z_AXIS]);
|
||||
Printer::startProbing(true);
|
||||
}
|
||||
#endif // DELTA
|
||||
#endif // BED_CORRECTION_METHOD == 1
|
||||
if(!measureAutolevelPlane(plane)) {
|
||||
Com::printErrorFLN(PSTR("Probing had returned errors - autoleveling canceled."));
|
||||
return false;
|
||||
}
|
||||
correctAutolevel(com,plane);
|
||||
|
||||
// Leveling is finished now update own positions and store leveling data if needed
|
||||
//float currentZ = plane.z((float)Printer::currentPositionSteps[X_AXIS] * Printer::invAxisStepsPerMM[X_AXIS],(float)Printer::currentPositionSteps[Y_AXIS] * Printer::invAxisStepsPerMM[Y_AXIS]);
|
||||
float currentZ = plane.z(0.0,0.0); // we rotated around this point, so that is now z height
|
||||
Com::printF(PSTR("CurrentZ:"),currentZ);
|
||||
Com::printFLN(PSTR(" atZ:"),Printer::currentPosition[Z_AXIS]);
|
||||
// With max z endstop we adjust zlength so after next homing we have also a calibrated printer
|
||||
Printer::zMin = 0;
|
||||
#if MAX_HARDWARE_ENDSTOP_Z
|
||||
//float xRot,yRot,zRot;
|
||||
//Printer::transformFromPrinter(Printer::currentPosition[X_AXIS],Printer::currentPosition[Y_AXIS],Printer::currentPosition[Z_AXIS],xRot,yRot,zRot);
|
||||
//Com::printFLN(PSTR("Z after rotation:"),zRot);
|
||||
// With max z endstop we adjust zlength so after next homing we have also a calibrated printer
|
||||
if(s != 0) {
|
||||
// at origin rotations have no influence so use values there to update
|
||||
Printer::zLength += currentZ - Printer::currentPosition[Z_AXIS];
|
||||
//Printer::zLength += /*currentZ*/ plane.z((float)Printer::currentPositionSteps[X_AXIS] * Printer::invAxisStepsPerMM[X_AXIS],(float)Printer::currentPositionSteps[Y_AXIS] * Printer::invAxisStepsPerMM[Y_AXIS]) - zRot;
|
||||
Com::printFLN(Com::tZProbePrinterHeight, Printer::zLength);
|
||||
}
|
||||
#endif
|
||||
Printer::currentPositionSteps[Z_AXIS] = currentZ * Printer::axisStepsPerMM[Z_AXIS];
|
||||
Printer::updateCurrentPosition(true); // set position based on steps position
|
||||
#if BED_CORRECTION_METHOD == 1
|
||||
if(fabs(plane.a) < 0.00025 && fabsf(plane.b) < 0.00025 )
|
||||
break; // we reached achievable precision so we can stop
|
||||
}
|
||||
#endif // BED_CORRECTION_METHOD == 1
|
||||
Printer::updateDerivedParameter();
|
||||
Printer::finishProbing();
|
||||
#if BED_CORRECTION_METHOD != 1
|
||||
Printer::setAutolevelActive(true); // only for software correction or we can spare the comp. time
|
||||
#endif
|
||||
if(s >= 2) {
|
||||
EEPROM::storeDataIntoEEPROM();
|
||||
}
|
||||
Printer::updateCurrentPosition(true);
|
||||
Commands::printCurrentPosition(PSTR("G32 "));
|
||||
#if DISTORTION_CORRECTION
|
||||
if(distEnabled)
|
||||
Printer::distortion.enable(false); // if level has changed, distortion is also invalid
|
||||
#endif
|
||||
#if DRIVE_SYSTEM == DELTA
|
||||
Printer::homeAxis(true, true, true); // shifting z makes positioning invalid, need to recalibrate
|
||||
#endif
|
||||
Printer::feedrate = oldFeedrate;
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void Printer::setAutolevelActive(bool on) {
|
||||
#if FEATURE_AUTOLEVEL
|
||||
if(on == isAutolevelActive()) return;
|
||||
flag0 = (on ? flag0 | PRINTER_FLAG0_AUTOLEVEL_ACTIVE : flag0 & ~PRINTER_FLAG0_AUTOLEVEL_ACTIVE);
|
||||
if(on)
|
||||
Com::printInfoFLN(Com::tAutolevelEnabled);
|
||||
else
|
||||
Com::printInfoFLN(Com::tAutolevelDisabled);
|
||||
updateCurrentPosition(false);
|
||||
#endif // FEATURE_AUTOLEVEL
|
||||
}
|
||||
#if MAX_HARDWARE_ENDSTOP_Z
|
||||
float Printer::runZMaxProbe() {
|
||||
#if NONLINEAR_SYSTEM
|
||||
long startZ = realDeltaPositionSteps[Z_AXIS] = currentNonlinearPositionSteps[Z_AXIS]; // update real
|
||||
#endif
|
||||
Commands::waitUntilEndOfAllMoves();
|
||||
long probeDepth = 2*(Printer::zMaxSteps-Printer::zMinSteps);
|
||||
stepsRemainingAtZHit = -1;
|
||||
setZProbingActive(true);
|
||||
PrintLine::moveRelativeDistanceInSteps(0,0,probeDepth,0,EEPROM::zProbeSpeed(),true,true);
|
||||
if(stepsRemainingAtZHit < 0) {
|
||||
Com::printErrorFLN(PSTR("z-max homing failed"));
|
||||
return ILLEGAL_Z_PROBE;
|
||||
}
|
||||
setZProbingActive(false);
|
||||
currentPositionSteps[Z_AXIS] -= stepsRemainingAtZHit;
|
||||
#if NONLINEAR_SYSTEM
|
||||
probeDepth -= (realDeltaPositionSteps[Z_AXIS] - startZ);
|
||||
#else
|
||||
probeDepth -= stepsRemainingAtZHit;
|
||||
#endif
|
||||
float distance = (float)probeDepth * invAxisStepsPerMM[Z_AXIS];
|
||||
Com::printF(Com::tZProbeMax,distance);
|
||||
Com::printF(Com::tSpaceXColon,realXPosition());
|
||||
Com::printFLN(Com::tSpaceYColon,realYPosition());
|
||||
PrintLine::moveRelativeDistanceInSteps(0,0,-probeDepth,0,EEPROM::zProbeSpeed(),true,true);
|
||||
return distance;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if FEATURE_Z_PROBE
|
||||
void Printer::startProbing(bool runScript) {
|
||||
float oldOffX = Printer::offsetX;
|
||||
float oldOffY = Printer::offsetY;
|
||||
float oldOffZ = Printer::offsetZ;
|
||||
if(runScript)
|
||||
GCode::executeFString(Com::tZProbeStartScript);
|
||||
float maxStartHeight = EEPROM::zProbeBedDistance() + (EEPROM::zProbeHeight() > 0 ? EEPROM::zProbeHeight() : 0) + 0.1;
|
||||
if(currentPosition[Z_AXIS] > maxStartHeight) {
|
||||
moveTo(IGNORE_COORDINATE, IGNORE_COORDINATE, maxStartHeight, IGNORE_COORDINATE, homingFeedrate[Z_AXIS]);
|
||||
}
|
||||
// Fix position to be inside print area when probe is enabled
|
||||
float ZPOffsetX = EEPROM::zProbeXOffset();
|
||||
float ZPOffsetY = EEPROM::zProbeYOffset();
|
||||
float xExtra = 0,yExtra = 0;
|
||||
if(ZPOffsetX > 0 && Printer::currentPosition[X_AXIS] - ZPOffsetX < Printer::xMin)
|
||||
xExtra = Printer::xMin + ZPOffsetX - Printer::currentPosition[X_AXIS];
|
||||
if(ZPOffsetY > 0 && Printer::currentPosition[Y_AXIS] - ZPOffsetY < Printer::yMin)
|
||||
yExtra = Printer::yMin + ZPOffsetY - Printer::currentPosition[Y_AXIS];
|
||||
if(ZPOffsetX < 0 && Printer::currentPosition[X_AXIS] - ZPOffsetX > Printer::xMin + Printer::xLength)
|
||||
xExtra = Printer::xMin + Printer::xLength + ZPOffsetX - Printer::currentPosition[X_AXIS];
|
||||
if(ZPOffsetY < 0 && Printer::currentPosition[Y_AXIS] - ZPOffsetY > Printer::yMin + Printer::yLength)
|
||||
yExtra = Printer::yMin + Printer::yLength + ZPOffsetY - Printer::currentPosition[Y_AXIS];
|
||||
// Update position
|
||||
Printer::offsetX = -ZPOffsetX;
|
||||
Printer::offsetY = -ZPOffsetY;
|
||||
Printer::offsetZ = 0; // we correct this with probe height
|
||||
PrintLine::moveRelativeDistanceInSteps((Printer::offsetX - oldOffX + xExtra) * Printer::axisStepsPerMM[X_AXIS],
|
||||
(Printer::offsetY - oldOffY + yExtra) * Printer::axisStepsPerMM[Y_AXIS],
|
||||
0, 0, EEPROM::zProbeXYSpeed(), true, ALWAYS_CHECK_ENDSTOPS);
|
||||
updateCurrentPosition(false);
|
||||
}
|
||||
|
||||
void Printer::finishProbing() {
|
||||
float xExtra = 0,yExtra = 0;
|
||||
float oldOffX = Printer::offsetX;
|
||||
float oldOffY = Printer::offsetY;
|
||||
float oldOffZ = Printer::offsetZ;
|
||||
GCode::executeFString(Com::tZProbeEndScript);
|
||||
if(Extruder::current) {
|
||||
Printer::offsetX = -Extruder::current->xOffset * Printer::invAxisStepsPerMM[X_AXIS];
|
||||
Printer::offsetY = -Extruder::current->yOffset * Printer::invAxisStepsPerMM[Y_AXIS];
|
||||
Printer::offsetZ = -Extruder::current->zOffset * Printer::invAxisStepsPerMM[Z_AXIS];
|
||||
}
|
||||
float ZPOffsetX = oldOffX - Printer::offsetX;
|
||||
float ZPOffsetY = oldOffY - Printer::offsetY;
|
||||
if(ZPOffsetX > 0 && Printer::currentPosition[X_AXIS] - ZPOffsetX < Printer::xMin)
|
||||
xExtra = Printer::xMin + ZPOffsetX - Printer::currentPosition[X_AXIS];
|
||||
if(ZPOffsetY > 0 && Printer::currentPosition[Y_AXIS] - ZPOffsetY < Printer::yMin)
|
||||
yExtra = Printer::yMin + ZPOffsetY - Printer::currentPosition[Y_AXIS];
|
||||
if(ZPOffsetX < 0 && Printer::currentPosition[X_AXIS] - ZPOffsetX > Printer::xMin + Printer::xLength)
|
||||
xExtra = Printer::xMin + Printer::xLength + ZPOffsetX - Printer::currentPosition[X_AXIS];
|
||||
if(ZPOffsetY < 0 && Printer::currentPosition[Y_AXIS] - ZPOffsetY > Printer::yMin + Printer::yLength)
|
||||
yExtra = Printer::yMin + Printer::yLength + ZPOffsetY - Printer::currentPosition[Y_AXIS];
|
||||
PrintLine::moveRelativeDistanceInSteps((xExtra - ZPOffsetX) * Printer::axisStepsPerMM[X_AXIS],
|
||||
(yExtra - ZPOffsetY) * Printer::axisStepsPerMM[Y_AXIS],
|
||||
(Printer::offsetZ - oldOffZ) * Printer::axisStepsPerMM[Z_AXIS], 0, EEPROM::zProbeXYSpeed(), true, ALWAYS_CHECK_ENDSTOPS);
|
||||
updateCurrentPosition(false);
|
||||
}
|
||||
|
||||
/*
|
||||
This is the most important function for bed leveling. It does
|
||||
1. Run probe start script if first = true and runStartScript = true
|
||||
2. Position zProbe at current position if first = true. If we are more then maxStartHeight away from bed we also go down to that distance.
|
||||
3. Measure the the steps until probe hits the bed.
|
||||
4. Undo positioning to z probe and run finish script if last = true.
|
||||
|
||||
Now we compute the nozzle height as follows:
|
||||
a) Compute average height from repeated measurements
|
||||
b) Add zProbeHeight to correct difference between triggering point and nozzle height above bed
|
||||
c) If Z_PROBE_Z_OFFSET_MODE == 1 we add zProbeZOffset() that is coating thickness if we measure below coating with indictive sensor.
|
||||
d) Add distortion correction.
|
||||
e) Add bending correction
|
||||
|
||||
Then we return the measured and corrected z distance.
|
||||
*/
|
||||
float Printer::runZProbe(bool first,bool last,uint8_t repeat,bool runStartScript) {
|
||||
float oldOffX = Printer::offsetX;
|
||||
float oldOffY = Printer::offsetY;
|
||||
float oldOffZ = Printer::offsetZ;
|
||||
if(first)
|
||||
startProbing(runStartScript);
|
||||
Commands::waitUntilEndOfAllMoves();
|
||||
int32_t sum = 0, probeDepth;
|
||||
int32_t shortMove = static_cast<int32_t>((float)Z_PROBE_SWITCHING_DISTANCE * axisStepsPerMM[Z_AXIS]); // distance to go up for repeated moves
|
||||
int32_t lastCorrection = currentPositionSteps[Z_AXIS]; // starting position
|
||||
#if NONLINEAR_SYSTEM
|
||||
realDeltaPositionSteps[Z_AXIS] = currentNonlinearPositionSteps[Z_AXIS]; // update real
|
||||
#endif
|
||||
//int32_t updateZ = 0;
|
||||
waitForZProbeStart();
|
||||
Endstops::update();
|
||||
Endstops::update();
|
||||
if(Endstops::zProbe()) {
|
||||
Com::printErrorFLN(PSTR("z-probe triggered before starting probing."));
|
||||
return ILLEGAL_Z_PROBE;
|
||||
}
|
||||
for(int8_t r = 0; r < repeat; r++) {
|
||||
probeDepth = 2 * (Printer::zMaxSteps - Printer::zMinSteps); // probe should always hit within this distance
|
||||
stepsRemainingAtZHit = -1; // Marker that we did not hit z probe
|
||||
//int32_t offx = axisStepsPerMM[X_AXIS] * EEPROM::zProbeXOffset();
|
||||
//int32_t offy = axisStepsPerMM[Y_AXIS] * EEPROM::zProbeYOffset();
|
||||
//PrintLine::moveRelativeDistanceInSteps(-offx,-offy,0,0,EEPROM::zProbeXYSpeed(),true,true);
|
||||
setZProbingActive(true);
|
||||
PrintLine::moveRelativeDistanceInSteps(0, 0, -probeDepth, 0, EEPROM::zProbeSpeed(), true, true);
|
||||
if(stepsRemainingAtZHit < 0) {
|
||||
Com::printErrorFLN(Com::tZProbeFailed);
|
||||
return ILLEGAL_Z_PROBE;
|
||||
}
|
||||
setZProbingActive(false);
|
||||
#if NONLINEAR_SYSTEM
|
||||
stepsRemainingAtZHit = realDeltaPositionSteps[C_TOWER] - currentNonlinearPositionSteps[C_TOWER]; // nonlinear moves may split z so stepsRemainingAtZHit is only what is left from last segment not total move. This corrects the problem.
|
||||
#endif
|
||||
#if DRIVE_SYSTEM == DELTA
|
||||
currentNonlinearPositionSteps[A_TOWER] += stepsRemainingAtZHit; // Update difference
|
||||
currentNonlinearPositionSteps[B_TOWER] += stepsRemainingAtZHit;
|
||||
currentNonlinearPositionSteps[C_TOWER] += stepsRemainingAtZHit;
|
||||
#endif
|
||||
currentPositionSteps[Z_AXIS] += stepsRemainingAtZHit; // now current position is correct
|
||||
sum += lastCorrection - currentPositionSteps[Z_AXIS];
|
||||
if(r + 1 < repeat) {
|
||||
// go only shortest possible move up for repetitions
|
||||
PrintLine::moveRelativeDistanceInSteps(0, 0, shortMove, 0, EEPROM::zProbeSpeed(), true, true);
|
||||
if(Endstops::zProbe()) {
|
||||
Com::printErrorFLN(PSTR("z-probe did not untrigger on repetitive measurement - maybe you need to increase distance!"));
|
||||
return ILLEGAL_Z_PROBE;
|
||||
}
|
||||
}
|
||||
}
|
||||
float distance = static_cast<float>(sum) * invAxisStepsPerMM[Z_AXIS] / static_cast<float>(repeat) + EEPROM::zProbeHeight();
|
||||
//Com::printFLN(PSTR("OrigDistance:"),distance);
|
||||
#if Z_PROBE_Z_OFFSET_MODE == 1
|
||||
distance += EEPROM::zProbeZOffset(); // We measured including coating, so we need to add coating thickness!
|
||||
#endif
|
||||
#if DISTORTION_CORRECTION
|
||||
float zCorr = 0;
|
||||
if(Printer::distortion.isEnabled()) {
|
||||
zCorr = distortion.correct(currentPositionSteps[X_AXIS] + EEPROM::zProbeXOffset() * axisStepsPerMM[X_AXIS],currentPositionSteps[Y_AXIS]
|
||||
+ EEPROM::zProbeYOffset() * axisStepsPerMM[Y_AXIS],0) * invAxisStepsPerMM[Z_AXIS];
|
||||
distance += zCorr;
|
||||
}
|
||||
#endif
|
||||
distance += bendingCorrectionAt(currentPosition[X_AXIS], currentPosition[Y_AXIS]);
|
||||
Com::printF(Com::tZProbe, distance);
|
||||
Com::printF(Com::tSpaceXColon, realXPosition());
|
||||
#if DISTORTION_CORRECTION
|
||||
if(Printer::distortion.isEnabled()) {
|
||||
Com::printF(Com::tSpaceYColon, realYPosition());
|
||||
Com::printFLN(PSTR(" zCorr:"), zCorr);
|
||||
} else {
|
||||
Com::printFLN(Com::tSpaceYColon, realYPosition());
|
||||
}
|
||||
#else
|
||||
Com::printFLN(Com::tSpaceYColon, realYPosition());
|
||||
#endif
|
||||
// Go back to start position
|
||||
PrintLine::moveRelativeDistanceInSteps(0, 0, lastCorrection - currentPositionSteps[Z_AXIS], 0, EEPROM::zProbeSpeed(), true, true);
|
||||
if(Endstops::zProbe()) {
|
||||
Com::printErrorFLN(PSTR("z-probe did not untrigger after going back to start position."));
|
||||
return ILLEGAL_Z_PROBE;
|
||||
}
|
||||
//PrintLine::moveRelativeDistanceInSteps(offx,offy,0,0,EEPROM::zProbeXYSpeed(),true,true);
|
||||
if(last)
|
||||
finishProbing();
|
||||
return distance;
|
||||
}
|
||||
|
||||
float Printer::bendingCorrectionAt(float x, float y) {
|
||||
PlaneBuilder builder;
|
||||
builder.addPoint(EEPROM::zProbeX1(),EEPROM::zProbeY1(),EEPROM::bendingCorrectionA());
|
||||
builder.addPoint(EEPROM::zProbeX2(),EEPROM::zProbeY2(),EEPROM::bendingCorrectionB());
|
||||
builder.addPoint(EEPROM::zProbeX3(),EEPROM::zProbeY3(),EEPROM::bendingCorrectionC());
|
||||
Plane plane;
|
||||
builder.createPlane(plane,true);
|
||||
return plane.z(x,y);
|
||||
}
|
||||
|
||||
void Printer::waitForZProbeStart() {
|
||||
#if Z_PROBE_WAIT_BEFORE_TEST
|
||||
Endstops::update();
|
||||
Endstops::update(); // double test to get right signal. Needed for crosstalk protection.
|
||||
if(Endstops::zProbe()) return;
|
||||
#if UI_DISPLAY_TYPE != NO_DISPLAY
|
||||
uid.setStatusP(Com::tHitZProbe);
|
||||
uid.refreshPage();
|
||||
#endif
|
||||
#ifdef DEBUG_PRINT
|
||||
debugWaitLoop = 3;
|
||||
#endif
|
||||
while(!Endstops::zProbe()) {
|
||||
defaultLoopActions();
|
||||
Endstops::update();
|
||||
Endstops::update(); // double test to get right signal. Needed for crosstalk protection.
|
||||
}
|
||||
#ifdef DEBUG_PRINT
|
||||
debugWaitLoop = 4;
|
||||
#endif
|
||||
HAL::delayMilliseconds(30);
|
||||
while(Endstops::zProbe()) {
|
||||
defaultLoopActions();
|
||||
Endstops::update();
|
||||
Endstops::update(); // double test to get right signal. Needed for crosstalk protection.
|
||||
}
|
||||
HAL::delayMilliseconds(30);
|
||||
UI_CLEAR_STATUS;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
Transforms theoretical correct coordinates to corrected coordinates resulting from bed rotation
|
||||
and shear transformations.
|
||||
*/
|
||||
void Printer::transformToPrinter(float x,float y,float z,float &transX,float &transY,float &transZ) {
|
||||
#if FEATURE_AXISCOMP
|
||||
// Axis compensation:
|
||||
x = x + y * EEPROM::axisCompTanXY() + z * EEPROM::axisCompTanXZ();
|
||||
y = y + z * EEPROM::axisCompTanYZ();
|
||||
#endif
|
||||
#if BED_CORRECTION_METHOD != 1 && FEATURE_AUTOLEVEL
|
||||
if(isAutolevelActive()) {
|
||||
transX = x * autolevelTransformation[0] + y * autolevelTransformation[3] + z * autolevelTransformation[6];
|
||||
transY = x * autolevelTransformation[1] + y * autolevelTransformation[4] + z * autolevelTransformation[7];
|
||||
transZ = x * autolevelTransformation[2] + y * autolevelTransformation[5] + z * autolevelTransformation[8];
|
||||
} else {
|
||||
transX = x;
|
||||
transY = y;
|
||||
transZ = z;
|
||||
}
|
||||
#else
|
||||
transX = x;
|
||||
transY = y;
|
||||
transZ = z;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Transform back to real printer coordinates. */
|
||||
void Printer::transformFromPrinter(float x,float y,float z,float &transX,float &transY,float &transZ) {
|
||||
#if BED_CORRECTION_METHOD != 1 && FEATURE_AUTOLEVEL
|
||||
if(isAutolevelActive()) {
|
||||
transX = x * autolevelTransformation[0] + y * autolevelTransformation[1] + z * autolevelTransformation[2];
|
||||
transY = x * autolevelTransformation[3] + y * autolevelTransformation[4] + z * autolevelTransformation[5];
|
||||
transZ = x * autolevelTransformation[6] + y * autolevelTransformation[7] + z * autolevelTransformation[8];
|
||||
} else {
|
||||
transX = x;
|
||||
transY = y;
|
||||
transZ = z;
|
||||
}
|
||||
#else
|
||||
transX = x;
|
||||
transY = y;
|
||||
transZ = z;
|
||||
#endif
|
||||
#if FEATURE_AXISCOMP
|
||||
// Axis compensation:
|
||||
transY = transY - transZ * EEPROM::axisCompTanYZ();
|
||||
transX = transX - transY * EEPROM::axisCompTanXY() - transZ * EEPROM::axisCompTanXZ();
|
||||
#endif
|
||||
}
|
||||
#if FEATURE_AUTOLEVEL
|
||||
void Printer::resetTransformationMatrix(bool silent) {
|
||||
autolevelTransformation[0] = autolevelTransformation[4] = autolevelTransformation[8] = 1;
|
||||
autolevelTransformation[1] = autolevelTransformation[2] = autolevelTransformation[3] =
|
||||
autolevelTransformation[5] = autolevelTransformation[6] = autolevelTransformation[7] = 0;
|
||||
if(!silent)
|
||||
Com::printInfoFLN(Com::tAutolevelReset);
|
||||
}
|
||||
|
||||
void Printer::buildTransformationMatrix(Plane &plane) {
|
||||
float z0 = plane.z(0,0);
|
||||
float az = z0-plane.z(1,0); // ax = 1, ay = 0
|
||||
float bz = z0-plane.z(0,1); // bx = 0, by = 1
|
||||
// First z direction
|
||||
autolevelTransformation[6] = -az;
|
||||
autolevelTransformation[7] = -bz;
|
||||
autolevelTransformation[8] = 1;
|
||||
float len = sqrt(az * az + bz * bz + 1);
|
||||
autolevelTransformation[6] /= len;
|
||||
autolevelTransformation[7] /= len;
|
||||
autolevelTransformation[8] /= len;
|
||||
autolevelTransformation[0] = 1;
|
||||
autolevelTransformation[1] = 0;
|
||||
autolevelTransformation[2] = -autolevelTransformation[6]/autolevelTransformation[8];
|
||||
len = sqrt(autolevelTransformation[0] * autolevelTransformation[0] + autolevelTransformation[1] * autolevelTransformation[1] + autolevelTransformation[2] * autolevelTransformation[2]);
|
||||
autolevelTransformation[0] /= len;
|
||||
autolevelTransformation[1] /= len;
|
||||
autolevelTransformation[2] /= len;
|
||||
// cross(z,x) y,z)
|
||||
autolevelTransformation[3] = autolevelTransformation[7] * autolevelTransformation[2] - autolevelTransformation[8] * autolevelTransformation[1];
|
||||
autolevelTransformation[4] = autolevelTransformation[8] * autolevelTransformation[0] - autolevelTransformation[6] * autolevelTransformation[2];
|
||||
autolevelTransformation[5] = autolevelTransformation[6] * autolevelTransformation[1] - autolevelTransformation[7] * autolevelTransformation[0];
|
||||
len = sqrt(autolevelTransformation[3] * autolevelTransformation[3] + autolevelTransformation[4] * autolevelTransformation[4] + autolevelTransformation[5] * autolevelTransformation[5]);
|
||||
autolevelTransformation[3] /= len;
|
||||
autolevelTransformation[4] /= len;
|
||||
autolevelTransformation[5] /= len;
|
||||
|
||||
Com::printArrayFLN(Com::tTransformationMatrix,autolevelTransformation, 9, 6);
|
||||
}
|
||||
/*
|
||||
void Printer::buildTransformationMatrix(float h1,float h2,float h3) {
|
||||
float ax = EEPROM::zProbeX2() - EEPROM::zProbeX1();
|
||||
float ay = EEPROM::zProbeY2() - EEPROM::zProbeY1();
|
||||
float az = h1 - h2;
|
||||
float bx = EEPROM::zProbeX3() - EEPROM::zProbeX1();
|
||||
float by = EEPROM::zProbeY3() - EEPROM::zProbeY1();
|
||||
float bz = h1 - h3;
|
||||
// First z direction
|
||||
autolevelTransformation[6] = ay * bz - az * by;
|
||||
autolevelTransformation[7] = az * bx - ax * bz;
|
||||
autolevelTransformation[8] = ax * by - ay * bx;
|
||||
float len = sqrt(autolevelTransformation[6] * autolevelTransformation[6] + autolevelTransformation[7] * autolevelTransformation[7] + autolevelTransformation[8] * autolevelTransformation[8]);
|
||||
if(autolevelTransformation[8] < 0) len = -len;
|
||||
autolevelTransformation[6] /= len;
|
||||
autolevelTransformation[7] /= len;
|
||||
autolevelTransformation[8] /= len;
|
||||
autolevelTransformation[3] = 0;
|
||||
autolevelTransformation[4] = autolevelTransformation[8];
|
||||
autolevelTransformation[5] = -autolevelTransformation[7];
|
||||
// cross(y,z)
|
||||
autolevelTransformation[0] = autolevelTransformation[4] * autolevelTransformation[8] - autolevelTransformation[5] * autolevelTransformation[7];
|
||||
autolevelTransformation[1] = autolevelTransformation[5] * autolevelTransformation[6];// - autolevelTransformation[3] * autolevelTransformation[8];
|
||||
autolevelTransformation[2] = autolevelTransformation[3] * autolevelTransformation[7] - autolevelTransformation[4] * autolevelTransformation[6];
|
||||
len = sqrt(autolevelTransformation[0] * autolevelTransformation[0] + autolevelTransformation[1] * autolevelTransformation[1] + autolevelTransformation[2] * autolevelTransformation[2]);
|
||||
autolevelTransformation[0] /= len;
|
||||
autolevelTransformation[1] /= len;
|
||||
autolevelTransformation[2] /= len;
|
||||
len = sqrt(autolevelTransformation[4] * autolevelTransformation[4] + autolevelTransformation[5] * autolevelTransformation[5]);
|
||||
autolevelTransformation[4] /= len;
|
||||
autolevelTransformation[5] /= len;
|
||||
Com::printArrayFLN(Com::tTransformationMatrix,autolevelTransformation, 9, 6);
|
||||
}
|
||||
*/
|
||||
#endif
|
Plik diff jest za duży
Load Diff
|
@ -41,7 +41,8 @@ public:
|
|||
static void waitUntilEndOfAllBuffers();
|
||||
static void printCurrentPosition(FSTRINGPARAM(s));
|
||||
static void printTemperatures(bool showRaw = false);
|
||||
static void setFanSpeed(int speed,bool wait); /// Set fan speed 0..255
|
||||
static void setFanSpeed(int speed, bool immediately = false); /// Set fan speed 0..255
|
||||
static void setFan2Speed(int speed); /// Set fan speed 0..255
|
||||
static void changeFeedrateMultiply(int factorInPercent);
|
||||
static void changeFlowrateMultiply(int factorInPercent);
|
||||
static void reportPrinterUsage();
|
||||
|
|
|
@ -20,18 +20,28 @@
|
|||
*/
|
||||
|
||||
#include "Repetier.h"
|
||||
//Davinci Specific
|
||||
#include <string.h>
|
||||
|
||||
#if UI_DISPLAY_TYPE != NO_DISPLAY
|
||||
uint8_t Com::selectedLanguage;
|
||||
#endif
|
||||
|
||||
#ifndef MACHINE_TYPE
|
||||
#if DRIVE_SYSTEM == DELTA
|
||||
FSTRINGVALUE(Com::tFirmware,"FIRMWARE_NAME:Repetier_" REPETIER_VERSION " FIRMWARE_URL:https://github.com/repetier/Repetier-Firmware/ PROTOCOL_VERSION:1.0 MACHINE_TYPE:Delta EXTRUDER_COUNT:" XSTR(NUM_EXTRUDER) " REPETIER_PROTOCOL:3")
|
||||
#else
|
||||
#if DRIVE_SYSTEM == CARTESIAN
|
||||
#define MACHINE_TYPE "Delta"
|
||||
#elif DRIVE_SYSTEM == CARTESIAN
|
||||
//Davinci Specific
|
||||
FSTRINGVALUE(Com::tFirmware,"FIRMWARE_NAME:Repetier_" REPETIER_VERSION " FIRMWARE_URL:https://github.com/luc-github/Repetier-Firmware-0.92 PROTOCOL_VERSION:1.0 MACHINE_TYPE:DaVinci EXTRUDER_COUNT:" XSTR(NUM_EXTRUDER) " REPETIER_PROTOCOL:3")
|
||||
#define MACHINE_TYPE "DaVinci"
|
||||
#else
|
||||
FSTRINGVALUE(Com::tFirmware,"FIRMWARE_NAME:Repetier_" REPETIER_VERSION " FIRMWARE_URL:https://github.com/repetier/Repetier-Firmware/ PROTOCOL_VERSION:1.0 MACHINE_TYPE:Core_XY EXTRUDER_COUNT:" XSTR(NUM_EXTRUDER) " REPETIER_PROTOCOL:3")
|
||||
#define MACHINE_TYPE "Core_XY"
|
||||
#endif
|
||||
#endif
|
||||
#ifndef FIRMWARE_URL
|
||||
//Davinci Specific
|
||||
#define FIRMWARE_URL "https://github.com/luc-github/Repetier-Firmware-0.92/"
|
||||
#endif // FIRMWARE_URL
|
||||
FSTRINGVALUE(Com::tFirmware,"FIRMWARE_NAME:Repetier_" REPETIER_VERSION " FIRMWARE_URL:" FIRMWARE_URL " PROTOCOL_VERSION:1.0 MACHINE_TYPE:" MACHINE_TYPE " EXTRUDER_COUNT:" XSTR(NUM_EXTRUDER) " REPETIER_PROTOCOL:3")
|
||||
//Davinci Specific
|
||||
FSTRINGVALUE(Com::tReadInput,"Read input: ")
|
||||
FSTRINGVALUE(Com::tReset,RESET_IDENTIFIER)
|
||||
|
@ -39,11 +49,9 @@ FSTRINGVALUE(Com::tTempExtABS,"Temp Ext ABS:")
|
|||
FSTRINGVALUE(Com::tTempExtPLA,"Temp Ext PLA:")
|
||||
FSTRINGVALUE(Com::tTempBedABS,"Temp Bed ABS:")
|
||||
FSTRINGVALUE(Com::tTempBedPLA,"Temp Bed PLA:")
|
||||
|
||||
FSTRINGVALUE(Com::tLoadFeedRate,"Load Feed Rate:")
|
||||
FSTRINGVALUE(Com::tUnloadFeedRate,"Unload Feed Rate:")
|
||||
FSTRINGVALUE(Com::tUnloadLoadDistance,"Unload/Load Distance:")
|
||||
|
||||
FSTRINGVALUE(Com::tKeepLightOn,"Keep Light On:")
|
||||
FSTRINGVALUE(Com::tSensorOn,"Filament Sensor On:")
|
||||
FSTRINGVALUE(Com::tTopsensorOn,"Top Sensor On:")
|
||||
|
@ -60,6 +68,7 @@ FSTRINGVALUE(Com::tNAN,"NAN")
|
|||
FSTRINGVALUE(Com::tINF,"INF")
|
||||
FSTRINGVALUE(Com::tError,"Error:")
|
||||
FSTRINGVALUE(Com::tInfo,"Info:")
|
||||
//ESP8266 SPecific
|
||||
FSTRINGVALUE(Com::tStatus,"Status:")
|
||||
FSTRINGVALUE(Com::tWarning,"Warning:")
|
||||
FSTRINGVALUE(Com::tResend,"Resend:")
|
||||
|
@ -107,9 +116,24 @@ FSTRINGVALUE(Com::tSpaceRaw," RAW")
|
|||
FSTRINGVALUE(Com::tColon,":")
|
||||
FSTRINGVALUE(Com::tSlash,"/")
|
||||
FSTRINGVALUE(Com::tSpaceSlash," /")
|
||||
FSTRINGVALUE(Com::tFatal,"fatal:")
|
||||
#if JSON_OUTPUT
|
||||
FSTRINGVALUE(Com::tJSONDir,"{\"dir\":\"")
|
||||
FSTRINGVALUE(Com::tJSONFiles,"\",\"files\":[")
|
||||
FSTRINGVALUE(Com::tJSONArrayEnd,"]}")
|
||||
FSTRINGVALUE(Com::tJSONErrorStart,"{\"err\":\"")
|
||||
FSTRINGVALUE(Com::tJSONErrorEnd,"\"}")
|
||||
FSTRINGVALUE(Com::tJSONFileInfoStart, "{\"err\":0,\"size\":");
|
||||
FSTRINGVALUE(Com::tJSONFileInfoHeight, ",\"height\":");
|
||||
FSTRINGVALUE(Com::tJSONFileInfoLayerHeight, ",\"layerHeight\":");
|
||||
FSTRINGVALUE(Com::tJSONFileInfoFilament, ",\"filament\":[");
|
||||
FSTRINGVALUE(Com::tJSONFileInfoGeneratedBy, "],\"generatedBy\":\"");
|
||||
FSTRINGVALUE(Com::tJSONFileInfoName, ",\"fileName\":\"");
|
||||
#endif // JSON_OUTPUT
|
||||
FSTRINGVALUE(Com::tSpeedMultiply,"SpeedMultiply:")
|
||||
FSTRINGVALUE(Com::tFlowMultiply,"FlowMultiply:")
|
||||
FSTRINGVALUE(Com::tFanspeed,"Fanspeed:")
|
||||
FSTRINGVALUE(Com::tFan2speed,"Fanspeed2:")
|
||||
FSTRINGVALUE(Com::tPrintedFilament,"Printed filament:")
|
||||
FSTRINGVALUE(Com::tPrintingTime,"Printing time:")
|
||||
FSTRINGVALUE(Com::tSpacem,"m ")
|
||||
|
@ -136,6 +160,7 @@ FSTRINGVALUE(Com::tYMinColon,"y_min:")
|
|||
FSTRINGVALUE(Com::tYMaxColon,"y_max:")
|
||||
FSTRINGVALUE(Com::tZMinColon,"z_min:")
|
||||
FSTRINGVALUE(Com::tZMaxColon,"z_max:")
|
||||
FSTRINGVALUE(Com::tZ2MinMaxColon,"z2_minmax:")
|
||||
FSTRINGVALUE(Com::tJerkColon,"Jerk:")
|
||||
FSTRINGVALUE(Com::tZJerkColon," ZJerk:")
|
||||
FSTRINGVALUE(Com::tLinearStepsColon," linear steps:")
|
||||
|
@ -145,15 +170,15 @@ FSTRINGVALUE(Com::tEEPROMUpdated,"EEPROM updated")
|
|||
|
||||
FSTRINGVALUE(Com::tLinearLColon,"linear L:")
|
||||
FSTRINGVALUE(Com::tQuadraticKColon," quadratic K:")
|
||||
FSTRINGVALUE(Com::tExtruderJam, UI_TEXT_EXTRUDER_JAM)
|
||||
FSTRINGVALUE(Com::tFilamentSlipping,"Filament slipping")
|
||||
FSTRINGVALUE(Com::tPauseCommunication,"// action:pause")
|
||||
FSTRINGVALUE(Com::tContinueCommunication,"// action:resume")
|
||||
#if DRIVE_SYSTEM == DELTA
|
||||
FSTRINGVALUE(Com::tMeasurementReset,"Measurement reset.")
|
||||
FSTRINGVALUE(Com::tMeasureDeltaSteps,"Measure/delta (Steps) =")
|
||||
FSTRINGVALUE(Com::tMeasureDelta,"Measure/delta =")
|
||||
FSTRINGVALUE(Com::tMeasureOriginReset,"Measured origin set. Measurement reset.")
|
||||
FSTRINGVALUE(Com::tMeasurementAbortedOrigin,"Origin measurement cannot be set. Use only Z-Cartesian (straight up and down) movements and try again.")
|
||||
FSTRINGVALUE(Com::tInvalidDeltaCoordinate,"Invalid delta coordinate - move ignored")
|
||||
FSTRINGVALUE(Com::tLevelingCalc,"Leveling calc:")
|
||||
FSTRINGVALUE(Com::tTower1,"Tower 1:")
|
||||
FSTRINGVALUE(Com::tTower2,"Tower 2:")
|
||||
|
@ -164,11 +189,21 @@ FSTRINGVALUE(Com::tDeltaAlphaC,"Alpha C(90):")
|
|||
FSTRINGVALUE(Com::tDeltaRadiusCorrectionA,"Delta Radius A(0):")
|
||||
FSTRINGVALUE(Com::tDeltaRadiusCorrectionB,"Delta Radius B(0):")
|
||||
FSTRINGVALUE(Com::tDeltaRadiusCorrectionC,"Delta Radius C(0):")
|
||||
FSTRINGVALUE(Com::tDBGDeltaNoMoveinDSegment,"No move in delta segment with > 1 segment. This should never happen and may cause a problem!")
|
||||
#endif // DRIVE_SYSTEM
|
||||
#if DRIVE_SYSTEM==TUGA
|
||||
#if NONLINEAR_SYSTEM
|
||||
#if DRIVE_SYSTEM == TUGA
|
||||
FSTRINGVALUE(Com::tInvalidDeltaCoordinate,"Invalid coordinate - move ignored")
|
||||
FSTRINGVALUE(Com::tDBGDeltaNoMoveinDSegment,"No move in delta segment with > 1 segment. This should never happen and may cause a problem!")
|
||||
#elif DRIVE_SYSTEM == DELTA
|
||||
FSTRINGVALUE(Com::tInvalidDeltaCoordinate,"Invalid delta coordinate - move ignored")
|
||||
FSTRINGVALUE(Com::tDBGDeltaNoMoveinDSegment,"No move in delta segment with > 1 segment. This should never happen and may cause a problem!")
|
||||
#else
|
||||
FSTRINGVALUE(Com::tInvalidDeltaCoordinate,"Invalid coordinate - move ignored")
|
||||
FSTRINGVALUE(Com::tDBGDeltaNoMoveinDSegment,"No move in segment with > 1 segment. This should never happen and may cause a problem!")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if DRIVE_SYSTEM==TUGA
|
||||
FSTRINGVALUE(Com::tEPRDiagonalRodLength,"Long arm length [mm]")
|
||||
#endif // DRIVE_SYSTEM
|
||||
#ifdef DEBUG_GENERIC
|
||||
|
@ -187,7 +222,7 @@ FSTRINGVALUE(Com::tAPIDClassic," Classic PID")
|
|||
FSTRINGVALUE(Com::tAPIDKp," Kp: ")
|
||||
FSTRINGVALUE(Com::tAPIDKi," Ki: ")
|
||||
FSTRINGVALUE(Com::tAPIDKd," Kd: ")
|
||||
FSTRINGVALUE(Com::tAPIDFailedHigh,"PID Autotune failed! Temperature to high")
|
||||
FSTRINGVALUE(Com::tAPIDFailedHigh,"PID Autotune failed! Temperature too high")
|
||||
FSTRINGVALUE(Com::tAPIDFailedTimeout,"PID Autotune failed! timeout")
|
||||
FSTRINGVALUE(Com::tAPIDFinished,"PID Autotune finished ! Place the Kp, Ki and Kd constants in the Configuration.h or EEPROM")
|
||||
FSTRINGVALUE(Com::tMTEMPColon,"MTEMP:")
|
||||
|
@ -257,14 +292,15 @@ FSTRINGVALUE(Com::tWait,WAITING_IDENTIFIER)
|
|||
FSTRINGVALUE(Com::tNoEEPROMSupport,"No EEPROM support compiled.\r\n")
|
||||
#else
|
||||
//Davinci Specific, manual leveling positions
|
||||
FSTRINGVALUE(Com::tManualProbeX1,"Manual-probe X1")
|
||||
FSTRINGVALUE(Com::tManualProbeY1,"Manual-probe Y1")
|
||||
FSTRINGVALUE(Com::tManualProbeX2,"Manual-probe X2")
|
||||
FSTRINGVALUE(Com::tManualProbeY2,"Manual-probe Y2")
|
||||
FSTRINGVALUE(Com::tManualProbeX3,"Manual-probe X3")
|
||||
FSTRINGVALUE(Com::tManualProbeY3,"Manual-probe Y3")
|
||||
FSTRINGVALUE(Com::tManualProbeX4,"Manual-probe X4")
|
||||
FSTRINGVALUE(Com::tManualProbeY4,"Manual-probe Y4")
|
||||
FSTRINGVALUE(Com::tManualProbeX1,"Manual-probe X1 [mm]")
|
||||
FSTRINGVALUE(Com::tManualProbeY1,"Manual-probe Y1 [mm]")
|
||||
FSTRINGVALUE(Com::tManualProbeX2,"Manual-probe X2 [mm]")
|
||||
FSTRINGVALUE(Com::tManualProbeY2,"Manual-probe Y2 [mm]")
|
||||
FSTRINGVALUE(Com::tManualProbeX3,"Manual-probe X3 [mm]")
|
||||
FSTRINGVALUE(Com::tManualProbeY3,"Manual-probe Y3 [mm]")
|
||||
FSTRINGVALUE(Com::tManualProbeX4,"Manual-probe X4 [mm]")
|
||||
FSTRINGVALUE(Com::tManualProbeY4,"Manual-probe Y4 [mm]")
|
||||
FSTRINGVALUE(Com::tZProbeOffsetZ, "Coating thickness [mm]")
|
||||
#if FEATURE_Z_PROBE
|
||||
FSTRINGVALUE(Com::tZProbeHeight,"Z-probe height [mm]")
|
||||
FSTRINGVALUE(Com::tZProbeBedDitance,"Max. z-probe - bed dist. [mm]")
|
||||
|
@ -272,12 +308,15 @@ FSTRINGVALUE(Com::tZProbeOffsetX,"Z-probe offset x [mm]")
|
|||
FSTRINGVALUE(Com::tZProbeOffsetY,"Z-probe offset y [mm]")
|
||||
FSTRINGVALUE(Com::tZProbeSpeed,"Z-probe speed [mm/s]")
|
||||
FSTRINGVALUE(Com::tZProbeSpeedXY,"Z-probe x-y-speed [mm/s]")
|
||||
FSTRINGVALUE(Com::tZProbeX1,"Z-probe X1")
|
||||
FSTRINGVALUE(Com::tZProbeY1,"Z-probe Y1")
|
||||
FSTRINGVALUE(Com::tZProbeX2,"Z-probe X2")
|
||||
FSTRINGVALUE(Com::tZProbeY2,"Z-probe Y2")
|
||||
FSTRINGVALUE(Com::tZProbeX3,"Z-probe X3")
|
||||
FSTRINGVALUE(Com::tZProbeY3,"Z-probe Y3")
|
||||
FSTRINGVALUE(Com::tZProbeX1,"Z-probe X1 [mm]")
|
||||
FSTRINGVALUE(Com::tZProbeY1,"Z-probe Y1 [mm]")
|
||||
FSTRINGVALUE(Com::tZProbeX2,"Z-probe X2 [mm]")
|
||||
FSTRINGVALUE(Com::tZProbeY2,"Z-probe Y2 [mm]")
|
||||
FSTRINGVALUE(Com::tZProbeX3,"Z-probe X3 [mm]")
|
||||
FSTRINGVALUE(Com::tZProbeY3,"Z-probe Y3 [mm]")
|
||||
FSTRINGVALUE(Com::zZProbeBendingCorA,"Z-probe bending correction A [mm]")
|
||||
FSTRINGVALUE(Com::zZProbeBendingCorB,"Z-probe bending correction B [mm]")
|
||||
FSTRINGVALUE(Com::zZProbeBendingCorC,"Z-probe bending correction C [mm]")
|
||||
#endif
|
||||
#if FEATURE_AXISCOMP
|
||||
FSTRINGVALUE(Com::tAxisCompTanXY,"tanXY Axis Compensation")
|
||||
|
@ -297,13 +336,14 @@ FSTRINGVALUE(Com::tEPR1,"EPR:1 ")
|
|||
FSTRINGVALUE(Com::tEPR2,"EPR:2 ")
|
||||
FSTRINGVALUE(Com::tEPR3,"EPR:3 ")
|
||||
FSTRINGVALUE(Com::tEPRBaudrate,"Baudrate")
|
||||
FSTRINGVALUE(Com::tLanguage,"Language")
|
||||
FSTRINGVALUE(Com::tEPRFilamentPrinted,"Filament printed [m]")
|
||||
FSTRINGVALUE(Com::tEPRPrinterActive,"Printer active [s]")
|
||||
FSTRINGVALUE(Com::tEPRMaxInactiveTime,"Max. inactive time [ms,0=off]")
|
||||
FSTRINGVALUE(Com::tEPRStopAfterInactivty,"Stop stepper after inactivity [ms,0=off]")
|
||||
FSTRINGVALUE(Com::tEPRXHomePos,"X home pos [mm]")
|
||||
FSTRINGVALUE(Com::tEPRYHomePos,"Y home pos [mm]")
|
||||
FSTRINGVALUE(Com::tEPRZHomePos,"Z home pos [mm]")
|
||||
FSTRINGVALUE(Com::tEPRXHomePos,"X min pos [mm]")
|
||||
FSTRINGVALUE(Com::tEPRYHomePos,"Y min pos [mm]")
|
||||
FSTRINGVALUE(Com::tEPRZHomePos,"Z min pos [mm]")
|
||||
FSTRINGVALUE(Com::tEPRXMaxLength,"X max length [mm]")
|
||||
FSTRINGVALUE(Com::tEPRYMaxLength,"Y max length [mm]")
|
||||
FSTRINGVALUE(Com::tEPRZMaxLength,"Z max length [mm]")
|
||||
|
@ -311,6 +351,11 @@ FSTRINGVALUE(Com::tEPRXBacklash,"X backlash [mm]")
|
|||
FSTRINGVALUE(Com::tEPRYBacklash,"Y backlash [mm]")
|
||||
FSTRINGVALUE(Com::tEPRZBacklash,"Z backlash [mm]")
|
||||
FSTRINGVALUE(Com::tEPRMaxJerk,"Max. jerk [mm/s]")
|
||||
FSTRINGVALUE(Com::tEPRAccelerationFactorAtTop,"Acceleration factor at top [%,100=like bottom]")
|
||||
#if NONLINEAR_SYSTEM
|
||||
FSTRINGVALUE(Com::tEPRSegmentsPerSecondPrint,"Segments/s for printing")
|
||||
FSTRINGVALUE(Com::tEPRSegmentsPerSecondTravel,"Segments/s for travel")
|
||||
#endif
|
||||
#if DRIVE_SYSTEM==DELTA
|
||||
FSTRINGVALUE(Com::tEPRZAcceleration,"Acceleration [mm/s^2]")
|
||||
FSTRINGVALUE(Com::tEPRZTravelAcceleration,"Travel acceleration [mm/s^2]")
|
||||
|
@ -320,8 +365,6 @@ FSTRINGVALUE(Com::tEPRZHomingFeedrate,"Homing feedrate [mm/s]")
|
|||
|
||||
FSTRINGVALUE(Com::tEPRDiagonalRodLength,"Diagonal rod length [mm]")
|
||||
FSTRINGVALUE(Com::tEPRHorizontalRadius,"Horizontal rod radius at 0,0 [mm]")
|
||||
FSTRINGVALUE(Com::tEPRSegmentsPerSecondPrint,"Segments/s for printing")
|
||||
FSTRINGVALUE(Com::tEPRSegmentsPerSecondTravel,"Segments/s for travel")
|
||||
|
||||
FSTRINGVALUE(Com::tEPRTowerXOffset,"Tower X endstop offset [steps]")
|
||||
FSTRINGVALUE(Com::tEPRTowerYOffset,"Tower Y endstop offset [steps]")
|
||||
|
@ -377,6 +420,7 @@ FSTRINGVALUE(Com::tEPRDGain,"PID D-gain")
|
|||
FSTRINGVALUE(Com::tEPRPIDMaxValue,"PID max value [0-255]")
|
||||
FSTRINGVALUE(Com::tEPRXOffset,"X-offset [steps]")
|
||||
FSTRINGVALUE(Com::tEPRYOffset,"Y-offset [steps]")
|
||||
FSTRINGVALUE(Com::tEPRZOffset,"Z-offset [steps]")
|
||||
FSTRINGVALUE(Com::tEPRStabilizeTime,"temp. stabilize time [s]")
|
||||
FSTRINGVALUE(Com::tEPRRetractionWhenHeating,"temp. for retraction when heating [C]")
|
||||
FSTRINGVALUE(Com::tEPRDistanceRetractHeating,"distance to retract when heating [mm]")
|
||||
|
@ -386,8 +430,8 @@ FSTRINGVALUE(Com::tEPRAdvanceL,"advance L [0=off]")
|
|||
|
||||
#endif
|
||||
#if SDSUPPORT
|
||||
FSTRINGVALUE(Com::tSDRemoved,UI_TEXT_SD_REMOVED)
|
||||
FSTRINGVALUE(Com::tSDInserted,UI_TEXT_SD_INSERTED)
|
||||
//FSTRINGVALUE(Com::tSDRemoved,UI_TEXT_SD_REMOVED)
|
||||
//FSTRINGVALUE(Com::tSDInserted,UI_TEXT_SD_INSERTED)
|
||||
FSTRINGVALUE(Com::tSDInitFail,"SD init fail")
|
||||
FSTRINGVALUE(Com::tErrorWritingToFile,"error writing to file")
|
||||
FSTRINGVALUE(Com::tBeginFileList,"Begin file list")
|
||||
|
@ -429,6 +473,17 @@ FSTRINGVALUE(Com::tEPRRetractionUndoSpeed,"Retraction undo speed")
|
|||
FSTRINGVALUE(Com::tConfig,"Config:")
|
||||
FSTRINGVALUE(Com::tExtrDot,"Extr.")
|
||||
|
||||
#if STEPPER_CURRENT_CONTROL == CURRENT_CONTROL_MCP4728
|
||||
FSTRINGVALUE(Com::tMCPEpromSettings, "MCP4728 DAC EEPROM Settings:")
|
||||
FSTRINGVALUE(Com::tMCPCurrentSettings,"MCP4728 DAC Current Settings:")
|
||||
#endif
|
||||
FSTRINGVALUE(Com::tPrinterModeFFF,"PrinterMode:FFF")
|
||||
FSTRINGVALUE(Com::tPrinterModeLaser,"PrinterMode:Laser")
|
||||
FSTRINGVALUE(Com::tPrinterModeCNC,"PrinterMode:CNC")
|
||||
#ifdef STARTUP_GCODE
|
||||
FSTRINGVALUE(Com::tStartupGCode,STARTUP_GCODE)
|
||||
#endif
|
||||
|
||||
void Com::config(FSTRINGPARAM(text)) {
|
||||
printF(tConfig);
|
||||
printFLN(text);
|
||||
|
@ -492,7 +547,7 @@ void Com::printFLN(FSTRINGPARAM(text),const char *msg) {
|
|||
|
||||
void Com::printF(FSTRINGPARAM(ptr)) {
|
||||
char c;
|
||||
while ((c=HAL::readFlashByte(ptr++)) != 0)
|
||||
while ((c = HAL::readFlashByte(ptr++)) != 0)
|
||||
HAL::serialWriteByte(c);
|
||||
}
|
||||
void Com::printF(FSTRINGPARAM(text),const char *msg) {
|
||||
|
@ -585,7 +640,8 @@ void Com::printFloat(float number, uint8_t digits)
|
|||
printF(tINF);
|
||||
return;
|
||||
}
|
||||
|
||||
//Davinci Specific
|
||||
//better rounding
|
||||
print(String(number,digits).c_str());
|
||||
/*// Handle negative numbers
|
||||
if (number < 0.0)
|
||||
|
@ -618,3 +674,4 @@ void Com::printFloat(float number, uint8_t digits)
|
|||
remainder -= toPrint;
|
||||
}*/
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ FSTRINGVAR(tNAN)
|
|||
FSTRINGVAR(tINF)
|
||||
FSTRINGVAR(tError)
|
||||
FSTRINGVAR(tInfo)
|
||||
//ESP8266 Specific
|
||||
FSTRINGVAR(tStatus)
|
||||
FSTRINGVAR(tWarning)
|
||||
FSTRINGVAR(tResend)
|
||||
|
@ -87,6 +88,20 @@ FSTRINGVAR(tFreeRAM)
|
|||
FSTRINGVAR(tXColon)
|
||||
FSTRINGVAR(tSlash)
|
||||
FSTRINGVAR(tSpaceSlash)
|
||||
FSTRINGVAR(tFatal)
|
||||
#if JSON_OUTPUT
|
||||
FSTRINGVAR(tJSONDir)
|
||||
FSTRINGVAR(tJSONFiles)
|
||||
FSTRINGVAR(tJSONArrayEnd)
|
||||
FSTRINGVAR(tJSONErrorStart)
|
||||
FSTRINGVAR(tJSONErrorEnd)
|
||||
FSTRINGVAR(tJSONFileInfoStart)
|
||||
FSTRINGVAR(tJSONFileInfoHeight)
|
||||
FSTRINGVAR(tJSONFileInfoLayerHeight)
|
||||
FSTRINGVAR(tJSONFileInfoFilament)
|
||||
FSTRINGVAR(tJSONFileInfoGeneratedBy)
|
||||
FSTRINGVAR(tJSONFileInfoName)
|
||||
#endif
|
||||
FSTRINGVAR(tSpaceXColon)
|
||||
FSTRINGVAR(tSpaceYColon)
|
||||
FSTRINGVAR(tSpaceZColon)
|
||||
|
@ -102,6 +117,7 @@ FSTRINGVAR(tColon)
|
|||
FSTRINGVAR(tSpeedMultiply)
|
||||
FSTRINGVAR(tFlowMultiply)
|
||||
FSTRINGVAR(tFanspeed)
|
||||
FSTRINGVAR(tFan2speed)
|
||||
FSTRINGVAR(tPrintedFilament)
|
||||
FSTRINGVAR(tPrintingTime)
|
||||
FSTRINGVAR(tSpacem)
|
||||
|
@ -127,6 +143,7 @@ FSTRINGVAR(tXMaxColon)
|
|||
FSTRINGVAR(tYMinColon)
|
||||
FSTRINGVAR(tYMaxColon)
|
||||
FSTRINGVAR(tZMinColon)
|
||||
FSTRINGVAR(tZ2MinMaxColon)
|
||||
FSTRINGVAR(tZMaxColon)
|
||||
FSTRINGVAR(tJerkColon)
|
||||
FSTRINGVAR(tZJerkColon)
|
||||
|
@ -136,15 +153,19 @@ FSTRINGVAR(tCommaSpeedEqual)
|
|||
FSTRINGVAR(tLinearLColon)
|
||||
FSTRINGVAR(tQuadraticKColon)
|
||||
FSTRINGVAR(tEEPROMUpdated)
|
||||
FSTRINGVAR(tExtruderJam)
|
||||
FSTRINGVAR(tFilamentSlipping)
|
||||
FSTRINGVAR(tPauseCommunication)
|
||||
FSTRINGVAR(tContinueCommunication)
|
||||
#if NONLINEAR_SYSTEM
|
||||
FSTRINGVAR(tInvalidDeltaCoordinate)
|
||||
FSTRINGVAR(tDBGDeltaNoMoveinDSegment)
|
||||
#endif
|
||||
#if DRIVE_SYSTEM == DELTA
|
||||
FSTRINGVAR(tMeasurementReset)
|
||||
FSTRINGVAR(tMeasureDeltaSteps)
|
||||
FSTRINGVAR(tMeasureDelta)
|
||||
FSTRINGVAR(tMeasureOriginReset)
|
||||
FSTRINGVAR(tMeasurementAbortedOrigin)
|
||||
FSTRINGVAR(tInvalidDeltaCoordinate)
|
||||
FSTRINGVAR(tLevelingCalc)
|
||||
FSTRINGVAR(tTower1)
|
||||
FSTRINGVAR(tTower2)
|
||||
|
@ -158,12 +179,9 @@ FSTRINGVAR(tDeltaRadiusCorrectionC)
|
|||
FSTRINGVAR(tDeltaDiagonalCorrectionA)
|
||||
FSTRINGVAR(tDeltaDiagonalCorrectionB)
|
||||
FSTRINGVAR(tDeltaDiagonalCorrectionC)
|
||||
FSTRINGVAR(tDBGDeltaNoMoveinDSegment)
|
||||
FSTRINGVAR(tEPRDeltaMaxRadius)
|
||||
#endif // DRIVE_SYSTEM
|
||||
#if DRIVE_SYSTEM==TUGA
|
||||
FSTRINGVAR(tInvalidDeltaCoordinate)
|
||||
FSTRINGVAR(tDBGDeltaNoMoveinDSegment)
|
||||
FSTRINGVAR(tEPRDiagonalRodLength)
|
||||
#endif
|
||||
#ifdef DEBUG_GENERIC
|
||||
|
@ -253,6 +271,7 @@ FSTRINGVAR(tWait)
|
|||
#if EEPROM_MODE==0
|
||||
FSTRINGVAR(tNoEEPROMSupport)
|
||||
#else
|
||||
FSTRINGVAR(tZProbeOffsetZ)
|
||||
#if FEATURE_Z_PROBE
|
||||
FSTRINGVAR(tZProbeHeight)
|
||||
FSTRINGVAR(tZProbeOffsetX)
|
||||
|
@ -265,6 +284,9 @@ FSTRINGVAR(tZProbeX2)
|
|||
FSTRINGVAR(tZProbeY2)
|
||||
FSTRINGVAR(tZProbeX3)
|
||||
FSTRINGVAR(tZProbeY3)
|
||||
FSTRINGVAR(zZProbeBendingCorA)
|
||||
FSTRINGVAR(zZProbeBendingCorB)
|
||||
FSTRINGVAR(zZProbeBendingCorC)
|
||||
#endif
|
||||
//Davinci Specific, manual leveling
|
||||
FSTRINGVAR(tManualProbeX1)
|
||||
|
@ -291,6 +313,7 @@ FSTRINGVAR(tEPR0)
|
|||
FSTRINGVAR(tEPR1)
|
||||
FSTRINGVAR(tEPR2)
|
||||
FSTRINGVAR(tEPR3)
|
||||
FSTRINGVAR(tLanguage)
|
||||
FSTRINGVAR(tEPRBaudrate)
|
||||
FSTRINGVAR(tEPRFilamentPrinted)
|
||||
FSTRINGVAR(tEPRPrinterActive)
|
||||
|
@ -308,10 +331,11 @@ FSTRINGVAR(tEPRYBacklash)
|
|||
FSTRINGVAR(tEPRZBacklash)
|
||||
FSTRINGVAR(tEPRZAcceleration)
|
||||
FSTRINGVAR(tEPRZTravelAcceleration)
|
||||
FSTRINGVAR(tEPRAccelerationFactorAtTop)
|
||||
FSTRINGVAR(tEPRZStepsPerMM)
|
||||
FSTRINGVAR(tEPRZMaxFeedrate)
|
||||
FSTRINGVAR(tEPRZHomingFeedrate)
|
||||
#if DRIVE_SYSTEM!=DELTA
|
||||
#if DRIVE_SYSTEM != DELTA
|
||||
FSTRINGVAR(tEPRMaxZJerk)
|
||||
FSTRINGVAR(tEPRXStepsPerMM)
|
||||
FSTRINGVAR(tEPRYStepsPerMM)
|
||||
|
@ -326,8 +350,6 @@ FSTRINGVAR(tEPRYTravelAcceleration)
|
|||
#else
|
||||
FSTRINGVAR(tEPRDiagonalRodLength)
|
||||
FSTRINGVAR(tEPRHorizontalRadius)
|
||||
FSTRINGVAR(tEPRSegmentsPerSecondPrint)
|
||||
FSTRINGVAR(tEPRSegmentsPerSecondTravel)
|
||||
FSTRINGVAR(tEPRTowerXOffset)
|
||||
FSTRINGVAR(tEPRTowerYOffset)
|
||||
FSTRINGVAR(tEPRTowerZOffset)
|
||||
|
@ -359,6 +381,7 @@ FSTRINGVAR(tEPRDGain)
|
|||
FSTRINGVAR(tEPRPIDMaxValue)
|
||||
FSTRINGVAR(tEPRXOffset)
|
||||
FSTRINGVAR(tEPRYOffset)
|
||||
FSTRINGVAR(tEPRZOffset)
|
||||
FSTRINGVAR(tEPRStabilizeTime)
|
||||
FSTRINGVAR(tEPRRetractionWhenHeating)
|
||||
FSTRINGVAR(tEPRDistanceRetractHeating)
|
||||
|
@ -367,8 +390,8 @@ FSTRINGVAR(tEPRAdvanceK)
|
|||
FSTRINGVAR(tEPRAdvanceL)
|
||||
#endif
|
||||
#if SDSUPPORT
|
||||
FSTRINGVAR(tSDRemoved)
|
||||
FSTRINGVAR(tSDInserted)
|
||||
//FSTRINGVAR(tSDRemoved)
|
||||
//FSTRINGVAR(tSDInserted)
|
||||
FSTRINGVAR(tSDInitFail)
|
||||
FSTRINGVAR(tErrorWritingToFile)
|
||||
FSTRINGVAR(tBeginFileList)
|
||||
|
@ -410,6 +433,21 @@ FSTRINGVAR(tEPRRetractionUndoSpeed)
|
|||
FSTRINGVAR(tConfig)
|
||||
FSTRINGVAR(tExtrDot)
|
||||
|
||||
#if STEPPER_CURRENT_CONTROL == CURRENT_CONTROL_MCP4728
|
||||
FSTRINGVAR(tMCPEpromSettings)
|
||||
FSTRINGVAR(tMCPCurrentSettings)
|
||||
#endif
|
||||
FSTRINGVAR(tPrinterModeFFF)
|
||||
FSTRINGVAR(tPrinterModeLaser)
|
||||
FSTRINGVAR(tPrinterModeCNC)
|
||||
#ifdef STARTUP_GCODE
|
||||
FSTRINGVAR(tStartupGCode)
|
||||
#endif
|
||||
#if NONLINEAR_SYSTEM
|
||||
FSTRINGVAR(tEPRSegmentsPerSecondPrint)
|
||||
FSTRINGVAR(tEPRSegmentsPerSecondTravel)
|
||||
#endif
|
||||
|
||||
static void config(FSTRINGPARAM(text));
|
||||
static void config(FSTRINGPARAM(text),int value);
|
||||
static void config(FSTRINGPARAM(text),const char *msg);
|
||||
|
@ -445,6 +483,11 @@ static inline void print(char c) {HAL::serialWriteByte(c);}
|
|||
static void printFloat(float number, uint8_t digits);
|
||||
static inline void print(float number) {printFloat(number, 6);}
|
||||
static inline void println() {HAL::serialWriteByte('\r');HAL::serialWriteByte('\n');}
|
||||
#if UI_DISPLAY_TYPE != NO_DISPLAY
|
||||
static const char* translatedF(int textId);
|
||||
static void selectLanguage(fast8_t lang);
|
||||
static uint8_t selectedLanguage;
|
||||
#endif
|
||||
protected:
|
||||
private:
|
||||
};
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -0,0 +1,224 @@
|
|||
#include "Repetier.h"
|
||||
|
||||
#if defined(NUM_MOTOR_DRIVERS) && NUM_MOTOR_DRIVERS > 0
|
||||
MOTOR_DRIVER_1(motorDriver1);
|
||||
#if NUM_MOTOR_DRIVERS > 1
|
||||
MOTOR_DRIVER_2(motorDriver2);
|
||||
#endif
|
||||
#if NUM_MOTOR_DRIVERS > 2
|
||||
MOTOR_DRIVER_3(motorDriver3);
|
||||
#endif
|
||||
#if NUM_MOTOR_DRIVERS > 3
|
||||
MOTOR_DRIVER_4(motorDriver4);
|
||||
#endif
|
||||
#if NUM_MOTOR_DRIVERS > 4
|
||||
MOTOR_DRIVER_5(motorDriver5);
|
||||
#endif
|
||||
#if NUM_MOTOR_DRIVERS > 5
|
||||
MOTOR_DRIVER_6(motorDriver6);
|
||||
#endif
|
||||
|
||||
MotorDriverInterface *motorDrivers[NUM_MOTOR_DRIVERS] =
|
||||
{
|
||||
&motorDriver1
|
||||
#if NUM_MOTOR_DRIVERS > 1
|
||||
, &motorDriver2
|
||||
#endif
|
||||
#if NUM_MOTOR_DRIVERS > 2
|
||||
, &motorDriver3
|
||||
#endif
|
||||
#if NUM_MOTOR_DRIVERS > 3
|
||||
, &motorDriver4
|
||||
#endif
|
||||
#if NUM_MOTOR_DRIVERS > 4
|
||||
, &motorDriver5
|
||||
#endif
|
||||
#if NUM_MOTOR_DRIVERS > 5
|
||||
, &motorDriver6
|
||||
#endif
|
||||
};
|
||||
|
||||
MotorDriverInterface *getMotorDriver(int idx)
|
||||
{
|
||||
return motorDrivers[idx];
|
||||
}
|
||||
|
||||
/**
|
||||
Run motor P until it is at position X
|
||||
*/
|
||||
void commandG201(GCode &code)
|
||||
{
|
||||
int id = 0;
|
||||
if(code.hasP())
|
||||
id = code.P;
|
||||
if(id < 0) id = 0;
|
||||
if(id >= NUM_MOTOR_DRIVERS) id = 0;
|
||||
//Davinci Specific
|
||||
//allow to change speed
|
||||
if(code.hasF())
|
||||
{
|
||||
if (TURNTABLE_MAX_SPEED > code.F) motorDrivers[id]->setdelayUS( 500000 / (code.F * motorDrivers[id]->getstepsPerMM()));
|
||||
else motorDrivers[id]->setdelayUS( 500000 / (TURNTABLE_MAX_SPEED * motorDrivers[id]->getstepsPerMM()));
|
||||
}
|
||||
//allow to use mm (X) or degres (E)
|
||||
if(!code.hasX() && !code.hasE()) return;
|
||||
if (code.hasX())motorDrivers[id]->gotoPosition(code.X); //move in mm
|
||||
else motorDrivers[id]->gotoPosition(TURNTABLE_MM_PER_DEG * code.E); //move in degres
|
||||
}
|
||||
|
||||
//G202 P<motorId> X<setpos> - Mark current position as X
|
||||
void commandG202(GCode &code)
|
||||
{
|
||||
int id = 0;
|
||||
if(code.hasP())
|
||||
id = code.P;
|
||||
if(id < 0) id = 0;
|
||||
if(id >= NUM_MOTOR_DRIVERS) id = 0;
|
||||
if(!code.hasX()) return;
|
||||
motorDrivers[id]->setCurrentAs(code.X);
|
||||
}
|
||||
//G203 P<motorId> - Report current motor position
|
||||
void commandG203(GCode &code)
|
||||
{
|
||||
int id = 0;
|
||||
if(code.hasP())
|
||||
id = code.P;
|
||||
if(id < 0) id = 0;
|
||||
if(id >= NUM_MOTOR_DRIVERS) id = 0;
|
||||
Com::printF(PSTR("Motor"),id);
|
||||
Com::printFLN(PSTR("Pos:"),motorDrivers[id]->getPosition());
|
||||
}
|
||||
//G204 P<motorId> S<0/1> - Enable/disable motor
|
||||
void commandG204(GCode &code)
|
||||
{
|
||||
int id = 0;
|
||||
if(code.hasP())
|
||||
id = code.P;
|
||||
if(id < 0) id = 0;
|
||||
if(id >= NUM_MOTOR_DRIVERS) id = 0;
|
||||
if(!code.hasS()) return;
|
||||
if(code.S)
|
||||
motorDrivers[id]->enable();
|
||||
else
|
||||
motorDrivers[id]->disable();
|
||||
}
|
||||
|
||||
void disableAllMotorDrivers()
|
||||
{
|
||||
for(int i = 0; i < NUM_MOTOR_DRIVERS; i++)
|
||||
motorDrivers[i]->disable();
|
||||
}
|
||||
void initializeAllMotorDrivers()
|
||||
{
|
||||
for(int i = 0; i < NUM_MOTOR_DRIVERS; i++)
|
||||
motorDrivers[i]->initialize();
|
||||
}
|
||||
|
||||
#endif // NUM_MOTOR_DRIVERS
|
||||
|
||||
#if defined(SUPPORT_LASER) && SUPPORT_LASER
|
||||
uint8_t LaserDriver::intensity = 255; // Intensity to use for next move queued if we want lasers. This is NOT the current value!
|
||||
bool LaserDriver::laserOn = false;
|
||||
void LaserDriver::initialize()
|
||||
{
|
||||
if(EVENT_INITALIZE_LASER)
|
||||
{
|
||||
#if LASER_PIN > -1
|
||||
SET_OUTPUT(LASER_PIN);
|
||||
#endif
|
||||
}
|
||||
changeIntensity(0);
|
||||
}
|
||||
void LaserDriver::changeIntensity(uint8_t newIntensity)
|
||||
{
|
||||
if(EVENT_SET_LASER(newIntensity))
|
||||
{
|
||||
// Default implementation
|
||||
#if LASER_PIN > -1
|
||||
WRITE(LASER_PIN,(LASER_ON_HIGH ? newIntensity > 199 : newIntensity < 200));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif // SUPPORT_LASER
|
||||
|
||||
#if defined(SUPPORT_CNC) && SUPPORT_CNC
|
||||
/**
|
||||
The CNC driver differs a bit from laser driver. Here only M3,M4,M5 have an influence on the spindle.
|
||||
The motor also keeps running for G0 moves. M3 and M4 wait for old moves to be finished and then enables
|
||||
the motor. It then waits CNC_WAIT_ON_ENABLE milliseconds for the spindle to reach target speed.
|
||||
*/
|
||||
|
||||
int8_t CNCDriver::direction = 0;
|
||||
/** Initialize cnc pins. EVENT_INITALIZE_CNC should return false to prevent default initalization.*/
|
||||
void CNCDriver::initialize()
|
||||
{
|
||||
if(EVENT_INITALIZE_CNC)
|
||||
{
|
||||
#if CNC_ENABLE_PIN > -1
|
||||
SET_OUTPUT(CNC_ENABLE_PIN);
|
||||
WRITE(CNC_ENABLE_PIN,!CNC_ENABLE_WITH);
|
||||
#endif
|
||||
#if CNC_DIRECTION_PIN > -1
|
||||
SET_OUTPUT(CNC_DIRECTION_PIN);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/** Turns off spindle. For event override implement
|
||||
EVENT_SPINDLE_OFF
|
||||
returning false.
|
||||
*/
|
||||
void CNCDriver::spindleOff()
|
||||
{
|
||||
if(direction == 0) return; // already off
|
||||
if(EVENT_SPINDLE_OFF)
|
||||
{
|
||||
#if CNC_ENABLE_PIN > -1
|
||||
WRITE(CNC_ENABLE_PIN,!CNC_ENABLE_WITH);
|
||||
#endif
|
||||
}
|
||||
HAL::delayMilliseconds(CNC_WAIT_ON_DISABLE);
|
||||
direction = 0;
|
||||
}
|
||||
/** Turns spindle on. Default implementation uses a enable pin CNC_ENABLE_PIN. If
|
||||
CNC_DIRECTION_PIN is not -1 it sets direction to CNC_DIRECTION_CW. rpm is ignored.
|
||||
To override with event system, return false for the event
|
||||
EVENT_SPINDLE_CW(rpm)
|
||||
*/
|
||||
void CNCDriver::spindleOnCW(int32_t rpm)
|
||||
{
|
||||
if(direction == 1)
|
||||
return;
|
||||
spindleOff();
|
||||
direction = 1;
|
||||
if(EVENT_SPINDLE_CW(rpm)) {
|
||||
#if CNC_DIRECTION_PIN > -1
|
||||
WRITE(CNC_DIRECTION_PIN, CNC_DIRECTION_CW);
|
||||
#endif
|
||||
#if CNC_ENABLE_PIN > -1
|
||||
WRITE(CNC_ENABLE_PIN, CNC_ENABLE_WITH);
|
||||
#endif
|
||||
}
|
||||
HAL::delayMilliseconds(CNC_WAIT_ON_ENABLE);
|
||||
}
|
||||
/** Turns spindle on. Default implementation uses a enable pin CNC_ENABLE_PIN. If
|
||||
CNC_DIRECTION_PIN is not -1 it sets direction to !CNC_DIRECTION_CW. rpm is ignored.
|
||||
To override with event system, return false for the event
|
||||
EVENT_SPINDLE_CCW(rpm)
|
||||
*/
|
||||
void CNCDriver::spindleOnCCW(int32_t rpm)
|
||||
{
|
||||
if(direction == -1)
|
||||
return;
|
||||
spindleOff();
|
||||
direction = -1;
|
||||
if(EVENT_SPINDLE_CW(rpm)) {
|
||||
#if CNC_DIRECTION_PIN > -1
|
||||
WRITE(CNC_DIRECTION_PIN, !CNC_DIRECTION_CW);
|
||||
#endif
|
||||
#if CNC_ENABLE_PIN > -1
|
||||
WRITE(CNC_ENABLE_PIN, CNC_ENABLE_WITH);
|
||||
#endif
|
||||
}
|
||||
HAL::delayMilliseconds(CNC_WAIT_ON_ENABLE);
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,177 @@
|
|||
#ifndef DRIVERS_H_INCLUDED
|
||||
#define DRIVERS_H_INCLUDED
|
||||
|
||||
/**
|
||||
For some special printers you need to control extra motors. Possible reasons are
|
||||
- Extruder switches
|
||||
- Clearing surface
|
||||
- Leveling
|
||||
|
||||
Repetier-Firmware supports up to 4 extra motors that can be controlled by
|
||||
G201 P<motorId> X<pos> - Go to position X with motor X
|
||||
G202 P<motorId> X<setpos> - Mark current position as X
|
||||
G203 P<motorId> - Report current motor position
|
||||
G204 P<motorId> S<0/1> - Enable/disable motor
|
||||
|
||||
These motors are already special and there might be different types, so we can not assume
|
||||
one class fits all needs. So to keep it simple, the firmware defines this general
|
||||
interface whcih a motor must implement. That way we can handle any type without changing
|
||||
the main code.
|
||||
*/
|
||||
class MotorDriverInterface
|
||||
{
|
||||
public:
|
||||
virtual void initialize() = 0;
|
||||
virtual float getPosition() = 0;
|
||||
virtual void setCurrentAs(float newPos) = 0;
|
||||
virtual void gotoPosition(float newPos) = 0;
|
||||
virtual void enable() = 0;
|
||||
virtual void disable() = 0;
|
||||
//Davinci Specific
|
||||
virtual void setdelayUS(int32_t newdelayUS) = 0;
|
||||
virtual int32_t getdelayUS() = 0;
|
||||
virtual void setstepsPerMM (float newstepsPerMM) = 0;
|
||||
virtual float getstepsPerMM ()= 0;
|
||||
};
|
||||
|
||||
/**
|
||||
Simple class to drive a stepper motor with fixed speed.
|
||||
*/
|
||||
template<int stepPin, int dirPin, int enablePin,bool invertDir, bool invertEnable>
|
||||
class StepperDriver : public MotorDriverInterface
|
||||
{
|
||||
int32_t position;
|
||||
int32_t delayUS;
|
||||
float stepsPerMM;
|
||||
public:
|
||||
//Davinci Specific
|
||||
void setdelayUS(int32_t newdelayUS)
|
||||
{
|
||||
delayUS=newdelayUS;
|
||||
}
|
||||
int32_t getdelayUS()
|
||||
{
|
||||
return delayUS;
|
||||
}
|
||||
void setstepsPerMM (float newstepsPerMM)
|
||||
{
|
||||
stepsPerMM = newstepsPerMM;
|
||||
}
|
||||
float getstepsPerMM ()
|
||||
{
|
||||
return stepsPerMM;
|
||||
}
|
||||
StepperDriver(float _stepsPerMM,float speed)
|
||||
{
|
||||
stepsPerMM = _stepsPerMM;
|
||||
delayUS = 500000 / (speed * stepsPerMM);
|
||||
}
|
||||
void initialize() {
|
||||
HAL::pinMode(enablePin, OUTPUT);
|
||||
HAL::pinMode(stepPin, OUTPUT);
|
||||
HAL::pinMode(dirPin, OUTPUT);
|
||||
HAL::digitalWrite(enablePin, !invertEnable);
|
||||
}
|
||||
float getPosition()
|
||||
{
|
||||
return position / stepsPerMM;
|
||||
}
|
||||
void setCurrentAs(float newPos)
|
||||
{
|
||||
position = floor(newPos * stepsPerMM + 0.5f);
|
||||
}
|
||||
void gotoPosition(float newPos)
|
||||
{
|
||||
enable();
|
||||
int32_t target = floor(newPos * stepsPerMM + 0.5f) - position;
|
||||
position += target;
|
||||
if(target > 0) {
|
||||
HAL::digitalWrite(dirPin, !invertDir);
|
||||
} else {
|
||||
target = -target;
|
||||
HAL::digitalWrite(dirPin, invertDir);
|
||||
}
|
||||
while(target) {
|
||||
HAL::digitalWrite(stepPin, HIGH);
|
||||
HAL::delayMicroseconds(delayUS);
|
||||
HAL::digitalWrite(stepPin, LOW);
|
||||
HAL::delayMicroseconds(delayUS);
|
||||
target--;
|
||||
HAL::pingWatchdog();
|
||||
if((target & 127) == 0) {
|
||||
Commands::checkForPeriodicalActions(false);
|
||||
GCode::keepAlive(Processing);
|
||||
}
|
||||
}
|
||||
}
|
||||
void enable()
|
||||
{
|
||||
HAL::digitalWrite(enablePin, invertEnable);
|
||||
}
|
||||
void disable()
|
||||
{
|
||||
HAL::digitalWrite(enablePin, !invertEnable);
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(NUM_MOTOR_DRIVERS) && NUM_MOTOR_DRIVERS > 0
|
||||
class GCode;
|
||||
extern void commandG201(GCode &code);
|
||||
extern void commandG202(GCode &code);
|
||||
extern void commandG203(GCode &code);
|
||||
extern void commandG204(GCode &code);
|
||||
extern void disableAllMotorDrivers();
|
||||
extern MotorDriverInterface *getMotorDriver(int idx);
|
||||
extern void initializeAllMotorDrivers();
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(SUPPORT_LASER) && SUPPORT_LASER
|
||||
/**
|
||||
With laser support you can exchange a extruder by a laser. A laser gets controlled by a digital pin.
|
||||
By default all intensities > 200 are always on, and lower values are always off. You can overwrite
|
||||
this with a programmed event EVENT_SET_LASER(intensity) that return false to signal the default
|
||||
implementation that it has set it's value already.
|
||||
EVENT_INITALIZE_LASER should return false to prevent default initialization.
|
||||
*/
|
||||
class LaserDriver {
|
||||
public:
|
||||
static uint8_t intensity; // Intensity to use for next move queued. This is NOT the current value!
|
||||
static bool laserOn; // Enabled by M3?
|
||||
static void initialize();
|
||||
static void changeIntensity(uint8_t newIntensity);
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(SUPPORT_CNC) && SUPPORT_CNC
|
||||
/**
|
||||
The CNC driver differs a bit from laser driver. Here only M3,M4,M5 have an influence on the spindle.
|
||||
The motor also keeps running for G0 moves. M3 and M4 wait for old moves to be finished and then enables
|
||||
the motor. It then waits CNC_WAIT_ON_ENABLE milliseconds for the spindle to reach target speed.
|
||||
*/
|
||||
class CNCDriver {
|
||||
public:
|
||||
static int8_t direction;
|
||||
/** Initialize cnc pins. EVENT_INITALIZE_CNC should return false to prevent default initalization.*/
|
||||
static void initialize();
|
||||
/** Turns off spindle. For event override implement
|
||||
EVENT_SPINDLE_OFF
|
||||
returning false.
|
||||
*/
|
||||
static void spindleOff();
|
||||
/** Turns spindle on. Default implementation uses a enable pin CNC_ENABLE_PIN. If
|
||||
CNC_DIRECTION_PIN is not -1 it sets direction to CNC_DIRECTION_CW. rpm is ignored.
|
||||
To override with event system, return false for the event
|
||||
EVENT_SPINDLE_CW(rpm)
|
||||
*/
|
||||
static void spindleOnCW(int32_t rpm);
|
||||
/** Turns spindle on. Default implementation uses a enable pin CNC_ENABLE_PIN. If
|
||||
CNC_DIRECTION_PIN is not -1 it sets direction to !CNC_DIRECTION_CW. rpm is ignored.
|
||||
To override with event system, return false for the event
|
||||
EVENT_SPINDLE_CCW(rpm)
|
||||
*/
|
||||
static void spindleOnCCW(int32_t rpm);
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // DRIVERS_H_INCLUDED
|
|
@ -29,7 +29,7 @@
|
|||
void EEPROM:: update(long P,uint8_t T,long S,float X)
|
||||
{
|
||||
#if EEPROM_MODE!=0
|
||||
if(T>=0 &&T<=3 && P>0 && P<=2048) //SDEEPROM_SIZE =2048 // Minimum size used by Eeprom.cpp
|
||||
if(T>=0 &&T<=3 && P>0 && P<=EEPROM_BYTES) // Minimum size used by Eeprom.cpp
|
||||
switch(T)
|
||||
{
|
||||
case EPR_TYPE_BYTE:
|
||||
|
@ -48,8 +48,8 @@ void EEPROM:: update(long P,uint8_t T,long S,float X)
|
|||
uint8_t newcheck = computeChecksum();
|
||||
if(newcheck != HAL::eprGetByte(EPR_INTEGRITY_BYTE))
|
||||
HAL::eprSetByte(EPR_INTEGRITY_BYTE,newcheck);
|
||||
readDataFromEEPROM();
|
||||
Extruder::selectExtruderById(Extruder::current->id);
|
||||
readDataFromEEPROM(true);
|
||||
//Extruder::selectExtruderById(Extruder::current->id);
|
||||
#else
|
||||
Com::printErrorF(Com::tNoEEPROMSupport);
|
||||
#endif
|
||||
|
@ -79,7 +79,8 @@ void EEPROM::update(GCode *com)
|
|||
uint8_t newcheck = computeChecksum();
|
||||
if(newcheck != HAL::eprGetByte(EPR_INTEGRITY_BYTE))
|
||||
HAL::eprSetByte(EPR_INTEGRITY_BYTE, newcheck);
|
||||
readDataFromEEPROM();
|
||||
bool includesEeprom = com->P >= EEPROM_EXTRUDER_OFFSET && com->P < EEPROM_EXTRUDER_OFFSET + 6 * EEPROM_EXTRUDER_LENGTH;
|
||||
readDataFromEEPROM(includesEeprom);
|
||||
#if MIXING_EXTRUDER
|
||||
Extruder::selectExtruderById(Extruder::activeMixingExtruder);
|
||||
#else
|
||||
|
@ -92,18 +93,26 @@ void EEPROM::update(GCode *com)
|
|||
|
||||
void EEPROM::restoreEEPROMSettingsFromConfiguration()
|
||||
{
|
||||
// can only be done right if we also update permanent values not cached!
|
||||
#if EEPROM_MODE != 0
|
||||
EEPROM::initalizeUncached();
|
||||
uint8_t newcheck = computeChecksum();
|
||||
if(newcheck != HAL::eprGetByte(EPR_INTEGRITY_BYTE))
|
||||
HAL::eprSetByte(EPR_INTEGRITY_BYTE, newcheck);
|
||||
baudrate = BAUDRATE;
|
||||
maxInactiveTime = MAX_INACTIVE_TIME * 1000L;
|
||||
//Davinci Specific
|
||||
#if CASE_LIGHTS_PIN > 0
|
||||
EEPROM::buselight = bool(CASE_LIGHT_DEFAULT_ON);
|
||||
#endif
|
||||
#if DAVINCI == 4
|
||||
EEPROM::rotate_speed = TURNTABLE_DEFAULT_SPEED;
|
||||
#endif
|
||||
#if BADGE_LIGHT_PIN > -1
|
||||
EEPROM::busebadgelight = bool(CASE_BADGE_LIGHT_DEFAULT_ON);
|
||||
#endif
|
||||
EEPROM::bkeeplighton = bool(CASE_KEEP_LIGHT_DEFAULT_ON);
|
||||
UIDisplay::display_mode=CASE_DISPLAY_MODE_DEFAULT;
|
||||
UIDisplay::display_mode = CASE_DISPLAY_MODE_DEFAULT;
|
||||
#if FEATURE_BEEPER
|
||||
HAL::enablesound = bool(CASE_SOUND_DEFAULT_ON);
|
||||
#endif
|
||||
|
@ -112,17 +121,17 @@ void EEPROM::restoreEEPROMSettingsFromConfiguration()
|
|||
#if ENABLE_WIFI
|
||||
HAL::bwifion = bool(CASE_WIFI_DEFAULT_ON);
|
||||
#endif
|
||||
EEPROM::ftemp_ext_pla=UI_SET_PRESET_EXTRUDER_TEMP_PLA;
|
||||
EEPROM::ftemp_ext_abs=UI_SET_PRESET_EXTRUDER_TEMP_ABS;
|
||||
EEPROM::ftemp_bed_pla=UI_SET_PRESET_HEATED_BED_TEMP_PLA;
|
||||
EEPROM::ftemp_bed_abs=UI_SET_PRESET_HEATED_BED_TEMP_ABS;
|
||||
EEPROM::loading_feed_rate=UI_SET_PRESET_LOADING_FEEDRATE;
|
||||
EEPROM::unloading_feed_rate=UI_SET_PRESET_UNLOADING_FEEDRATE;
|
||||
EEPROM::unloading_loading_distance=UI_SET_PRESET_UNLOAD_LOAD_DISTANCE;
|
||||
#if CASE_LIGHTS_PIN>=0
|
||||
EEPROM::ftemp_ext_pla = UI_SET_PRESET_EXTRUDER_TEMP_PLA;
|
||||
EEPROM::ftemp_ext_abs = UI_SET_PRESET_EXTRUDER_TEMP_ABS;
|
||||
EEPROM::ftemp_bed_pla = UI_SET_PRESET_HEATED_BED_TEMP_PLA;
|
||||
EEPROM::ftemp_bed_abs = UI_SET_PRESET_HEATED_BED_TEMP_ABS;
|
||||
EEPROM::loading_feed_rate = UI_SET_PRESET_LOADING_FEEDRATE;
|
||||
EEPROM::unloading_feed_rate = UI_SET_PRESET_UNLOADING_FEEDRATE;
|
||||
EEPROM::unloading_loading_distance = UI_SET_PRESET_UNLOAD_LOAD_DISTANCE;
|
||||
#if CASE_LIGHTS_PIN >= 0
|
||||
WRITE(CASE_LIGHTS_PIN, byte(EEPROM::buselight));
|
||||
#endif // CASE_LIGHTS_PIN
|
||||
#if BADGE_LIGHT_PIN>=0
|
||||
#if BADGE_LIGHT_PIN >= 0
|
||||
WRITE(BADGE_LIGHT_PIN, byte(EEPROM::busebadgelight & EEPROM::buselight));
|
||||
#endif // BADGE_LIGHT_PIN
|
||||
stepperInactiveTime = STEPPER_INACTIVE_TIME * 1000L;
|
||||
|
@ -165,6 +174,13 @@ void EEPROM::restoreEEPROMSettingsFromConfiguration()
|
|||
Printer::xMin = X_MIN_POS;
|
||||
Printer::yMin = Y_MIN_POS;
|
||||
Printer::zMin = Z_MIN_POS;
|
||||
#if NONLINEAR_SYSTEM
|
||||
#ifdef ROD_RADIUS
|
||||
Printer::radius0 = ROD_RADIUS;
|
||||
#else
|
||||
Printer::radius0 = 0;
|
||||
#endif
|
||||
#endif
|
||||
#if ENABLE_BACKLASH_COMPENSATION
|
||||
Printer::backlashX = X_BACKLASH;
|
||||
Printer::backlashY = Y_BACKLASH;
|
||||
|
@ -291,7 +307,7 @@ void EEPROM::restoreEEPROMSettingsFromConfiguration()
|
|||
e->advanceL = EXT3_ADVANCE_L;
|
||||
#endif
|
||||
#endif // NUM_EXTRUDER > 3
|
||||
#if NUM_EXTRUDER>4
|
||||
#if NUM_EXTRUDER > 4
|
||||
e = &extruder[4];
|
||||
e->stepsPerMM = EXT4_STEPS_PER_MM;
|
||||
e->maxFeedrate = EXT4_MAX_FEEDRATE;
|
||||
|
@ -321,7 +337,7 @@ void EEPROM::restoreEEPROMSettingsFromConfiguration()
|
|||
e->advanceL = EXT4_ADVANCE_L;
|
||||
#endif
|
||||
#endif // NUM_EXTRUDER > 4
|
||||
#if NUM_EXTRUDER>5
|
||||
#if NUM_EXTRUDER > 5
|
||||
e = &extruder[5];
|
||||
e->stepsPerMM = EXT5_STEPS_PER_MM;
|
||||
e->maxFeedrate = EXT5_MAX_FEEDRATE;
|
||||
|
@ -373,23 +389,26 @@ void EEPROM::restoreEEPROMSettingsFromConfiguration()
|
|||
|
||||
}
|
||||
//Davinci Specific
|
||||
bool EEPROM::buselight=false;
|
||||
bool EEPROM::busebadgelight=false;
|
||||
bool EEPROM::busesensor=false;
|
||||
bool EEPROM::btopsensor=false;
|
||||
bool EEPROM::bkeeplighton=true;
|
||||
float EEPROM::ftemp_ext_pla=UI_SET_PRESET_EXTRUDER_TEMP_PLA;
|
||||
float EEPROM::ftemp_ext_abs=UI_SET_PRESET_EXTRUDER_TEMP_ABS;
|
||||
float EEPROM::ftemp_bed_pla=UI_SET_PRESET_HEATED_BED_TEMP_PLA;
|
||||
float EEPROM::ftemp_bed_abs=UI_SET_PRESET_HEATED_BED_TEMP_ABS;
|
||||
float EEPROM::loading_feed_rate=UI_SET_PRESET_LOADING_FEEDRATE;
|
||||
float EEPROM::unloading_feed_rate=UI_SET_PRESET_UNLOADING_FEEDRATE;
|
||||
float EEPROM::unloading_loading_distance=UI_SET_PRESET_UNLOAD_LOAD_DISTANCE;
|
||||
#if DAVINCI == 4
|
||||
float EEPROM::rotate_speed = TURNTABLE_DEFAULT_SPEED;
|
||||
#endif
|
||||
bool EEPROM::buselight = false;
|
||||
bool EEPROM::busebadgelight = false;
|
||||
bool EEPROM::busesensor = false;
|
||||
bool EEPROM::btopsensor = false;
|
||||
bool EEPROM::bkeeplighton = true;
|
||||
float EEPROM::ftemp_ext_pla = UI_SET_PRESET_EXTRUDER_TEMP_PLA;
|
||||
float EEPROM::ftemp_ext_abs = UI_SET_PRESET_EXTRUDER_TEMP_ABS;
|
||||
float EEPROM::ftemp_bed_pla = UI_SET_PRESET_HEATED_BED_TEMP_PLA;
|
||||
float EEPROM::ftemp_bed_abs = UI_SET_PRESET_HEATED_BED_TEMP_ABS;
|
||||
float EEPROM::loading_feed_rate = UI_SET_PRESET_LOADING_FEEDRATE;
|
||||
float EEPROM::unloading_feed_rate = UI_SET_PRESET_UNLOADING_FEEDRATE;
|
||||
float EEPROM::unloading_loading_distance = UI_SET_PRESET_UNLOAD_LOAD_DISTANCE;
|
||||
|
||||
#if UI_AUTOLIGHTOFF_AFTER !=0
|
||||
millis_t EEPROM::timepowersaving=1000 * 60 * 30; //30 min
|
||||
#if UI_AUTOLIGHTOFF_AFTER != 0
|
||||
millis_t EEPROM::timepowersaving = 1000 * 60 * 30; //30 min
|
||||
#else
|
||||
millis_t EEPROM::timepowersaving=0;
|
||||
millis_t EEPROM::timepowersaving = 0;
|
||||
#endif
|
||||
|
||||
void EEPROM::storeDataIntoEEPROM(uint8_t corrupted)
|
||||
|
@ -473,7 +492,7 @@ void EEPROM::storeDataIntoEEPROM(uint8_t corrupted)
|
|||
#if FEATURE_BEEPER
|
||||
HAL::eprSetByte(EPR_SOUND_ON,HAL::enablesound);
|
||||
#endif
|
||||
#if UI_AUTOLIGHTOFF_AFTER !=0
|
||||
#if UI_AUTOLIGHTOFF_AFTER != 0
|
||||
HAL::eprSetInt32(EPR_POWERSAVE_AFTER_TIME,EEPROM::timepowersaving);
|
||||
#endif
|
||||
HAL::eprSetFloat(EPR_MANUAL_LEVEL_X1, MANUAL_LEVEL_X1);
|
||||
|
@ -504,6 +523,9 @@ void EEPROM::storeDataIntoEEPROM(uint8_t corrupted)
|
|||
HAL::eprSetByte(EPR_AUTOLEVEL_ACTIVE,Printer::isAutolevelActive());
|
||||
for(uint8_t i = 0; i < 9; i++)
|
||||
HAL::eprSetFloat(EPR_AUTOLEVEL_MATRIX + (((int)i) << 2),Printer::autolevelTransformation[i]);
|
||||
#endif
|
||||
#if UI_DISPLAY_TYPE != NO_DISPLAY
|
||||
HAL::eprSetByte(EPR_SELECTED_LANGUAGE,Com::selectedLanguage);
|
||||
#endif
|
||||
// now the extruder
|
||||
for(uint8_t i = 0; i < NUM_EXTRUDER; i++)
|
||||
|
@ -529,6 +551,7 @@ void EEPROM::storeDataIntoEEPROM(uint8_t corrupted)
|
|||
#endif
|
||||
HAL::eprSetInt32(o+EPR_EXTRUDER_X_OFFSET,e->xOffset);
|
||||
HAL::eprSetInt32(o+EPR_EXTRUDER_Y_OFFSET,e->yOffset);
|
||||
HAL::eprSetInt32(o+EPR_EXTRUDER_Z_OFFSET,e->zOffset);
|
||||
HAL::eprSetInt16(o+EPR_EXTRUDER_WATCH_PERIOD,e->watchPeriod);
|
||||
#if RETRACT_DURING_HEATUP
|
||||
HAL::eprSetInt16(o+EPR_EXTRUDER_WAIT_RETRACT_TEMP,e->waitRetractTemperature);
|
||||
|
@ -571,6 +594,7 @@ void EEPROM::initalizeUncached()
|
|||
HAL::eprSetFloat(EPR_Z_PROBE_XY_SPEED,Z_PROBE_XY_SPEED);
|
||||
HAL::eprSetFloat(EPR_Z_PROBE_X_OFFSET,Z_PROBE_X_OFFSET);
|
||||
HAL::eprSetFloat(EPR_Z_PROBE_Y_OFFSET,Z_PROBE_Y_OFFSET);
|
||||
HAL::eprSetFloat(EPR_Z_PROBE_Z_OFFSET,Z_PROBE_Z_OFFSET);
|
||||
HAL::eprSetFloat(EPR_Z_PROBE_X1,Z_PROBE_X1);
|
||||
HAL::eprSetFloat(EPR_Z_PROBE_Y1,Z_PROBE_Y1);
|
||||
HAL::eprSetFloat(EPR_Z_PROBE_X2,Z_PROBE_X2);
|
||||
|
@ -597,11 +621,14 @@ void EEPROM::initalizeUncached()
|
|||
HAL::eprSetFloat(EPR_AXISCOMP_TANYZ,AXISCOMP_TANYZ);
|
||||
HAL::eprSetFloat(EPR_AXISCOMP_TANXZ,AXISCOMP_TANXZ);
|
||||
HAL::eprSetFloat(EPR_Z_PROBE_BED_DISTANCE,Z_PROBE_BED_DISTANCE);
|
||||
Printer::zBedOffset = HAL::eprGetFloat(EPR_Z_PROBE_Z_OFFSET);
|
||||
#if NONLINEAR_SYSTEM
|
||||
HAL::eprSetInt16(EPR_DELTA_SEGMENTS_PER_SECOND_PRINT,DELTA_SEGMENTS_PER_SECOND_PRINT);
|
||||
HAL::eprSetInt16(EPR_DELTA_SEGMENTS_PER_SECOND_MOVE,DELTA_SEGMENTS_PER_SECOND_MOVE);
|
||||
#endif
|
||||
#if DRIVE_SYSTEM == DELTA
|
||||
HAL::eprSetFloat(EPR_DELTA_DIAGONAL_ROD_LENGTH,DELTA_DIAGONAL_ROD);
|
||||
HAL::eprSetFloat(EPR_DELTA_HORIZONTAL_RADIUS,ROD_RADIUS);
|
||||
HAL::eprSetInt16(EPR_DELTA_SEGMENTS_PER_SECOND_PRINT,DELTA_SEGMENTS_PER_SECOND_PRINT);
|
||||
HAL::eprSetInt16(EPR_DELTA_SEGMENTS_PER_SECOND_MOVE,DELTA_SEGMENTS_PER_SECOND_MOVE);
|
||||
HAL::eprSetInt16(EPR_DELTA_TOWERX_OFFSET_STEPS,DELTA_X_ENDSTOP_OFFSET_STEPS);
|
||||
HAL::eprSetInt16(EPR_DELTA_TOWERY_OFFSET_STEPS,DELTA_Y_ENDSTOP_OFFSET_STEPS);
|
||||
HAL::eprSetInt16(EPR_DELTA_TOWERZ_OFFSET_STEPS,DELTA_Z_ENDSTOP_OFFSET_STEPS);
|
||||
|
@ -629,13 +656,18 @@ void EEPROM::initalizeUncached()
|
|||
HAL::eprSetFloat(EPR_RETRACTION_UNDO_EXTRA_LONG_LENGTH,RETRACTION_UNDO_EXTRA_LONG_LENGTH);
|
||||
HAL::eprSetFloat(EPR_RETRACTION_UNDO_SPEED,RETRACTION_UNDO_SPEED);
|
||||
HAL::eprSetByte(EPR_AUTORETRACT_ENABLED,AUTORETRACT_ENABLED);
|
||||
HAL::eprSetFloat(EPR_BENDING_CORRECTION_A,BENDING_CORRECTION_A);
|
||||
HAL::eprSetFloat(EPR_BENDING_CORRECTION_B,BENDING_CORRECTION_B);
|
||||
HAL::eprSetFloat(EPR_BENDING_CORRECTION_C,BENDING_CORRECTION_C);
|
||||
HAL::eprSetFloat(EPR_ACCELERATION_FACTOR_TOP,ACCELERATION_FACTOR_TOP);
|
||||
|
||||
}
|
||||
|
||||
void EEPROM::readDataFromEEPROM()
|
||||
void EEPROM::readDataFromEEPROM(bool includeExtruder)
|
||||
{
|
||||
#if EEPROM_MODE != 0
|
||||
uint8_t version = HAL::eprGetByte(EPR_VERSION); // This is the saved version. Don't copy data not set in older versions!
|
||||
//Com::printFLN(PSTR("Detected EEPROM version:"),(int)version);
|
||||
baudrate = HAL::eprGetInt32(EPR_BAUDRATE);
|
||||
maxInactiveTime = HAL::eprGetInt32(EPR_MAX_INACTIVE_TIME);
|
||||
stepperInactiveTime = HAL::eprGetInt32(EPR_STEPPER_INACTIVE_TIME);
|
||||
|
@ -650,7 +682,7 @@ void EEPROM::readDataFromEEPROM()
|
|||
Printer::homingFeedrate[Y_AXIS] = HAL::eprGetFloat(EPR_Y_HOMING_FEEDRATE);
|
||||
Printer::homingFeedrate[Z_AXIS] = HAL::eprGetFloat(EPR_Z_HOMING_FEEDRATE);
|
||||
Printer::maxJerk = HAL::eprGetFloat(EPR_MAX_JERK);
|
||||
#if DRIVE_SYSTEM!=DELTA
|
||||
#if DRIVE_SYSTEM != DELTA
|
||||
Printer::maxZJerk = HAL::eprGetFloat(EPR_MAX_ZJERK);
|
||||
#endif
|
||||
#if RAMP_ACCELERATION
|
||||
|
@ -683,52 +715,52 @@ void EEPROM::readDataFromEEPROM()
|
|||
#endif
|
||||
//Davinci Specific
|
||||
#if CASE_LIGHTS_PIN > 0
|
||||
EEPROM::buselight=HAL::eprGetByte(EPR_LIGHT_ON);
|
||||
EEPROM::bkeeplighton=HAL::eprGetByte(EPR_KEEP_LIGHT_ON);
|
||||
EEPROM::buselight = HAL::eprGetByte(EPR_LIGHT_ON);
|
||||
EEPROM::bkeeplighton = HAL::eprGetByte(EPR_KEEP_LIGHT_ON);
|
||||
#endif
|
||||
#if BADGE_LIGHT_PIN > -1
|
||||
EEPROM::busebadgelight=HAL::eprGetByte(EPR_BADGE_LIGHT_ON);
|
||||
EEPROM::busebadgelight = HAL::eprGetByte(EPR_BADGE_LIGHT_ON);
|
||||
#endif
|
||||
UIDisplay::display_mode=HAL::eprGetByte(EPR_DISPLAY_MODE);
|
||||
//need to be sure a valid value is set
|
||||
if(!((UIDisplay::display_mode==ADVANCED_MODE)||(UIDisplay::display_mode==EASY_MODE)))UIDisplay::display_mode=ADVANCED_MODE;
|
||||
#if CASE_LIGHTS_PIN>=0
|
||||
WRITE(CASE_LIGHTS_PIN, byte(EEPROM::buselight));
|
||||
#endif // CASE_LIGHTS_PIN
|
||||
#if BADGE_LIGHT_PIN>=0
|
||||
WRITE(BADGE_LIGHT_PIN, byte(EEPROM::busebadgelight & EEPROM::buselight));
|
||||
#endif // BADGE_LIGHT_PIN
|
||||
UIDisplay::display_mode = HAL::eprGetByte(EPR_DISPLAY_MODE);
|
||||
//need to be sure a valid value is set
|
||||
if(!((UIDisplay::display_mode == ADVANCED_MODE)||(UIDisplay::display_mode == EASY_MODE)))UIDisplay::display_mode = ADVANCED_MODE;
|
||||
#if CASE_LIGHTS_PIN >= 0
|
||||
WRITE(CASE_LIGHTS_PIN, byte(EEPROM::buselight));
|
||||
#endif // CASE_LIGHTS_PIN
|
||||
#if BADGE_LIGHT_PIN >= 0
|
||||
WRITE(BADGE_LIGHT_PIN, byte(EEPROM::busebadgelight & EEPROM::buselight));
|
||||
#endif // BADGE_LIGHT_PIN
|
||||
#if defined(FIL_SENSOR1_PIN)
|
||||
EEPROM::busesensor=HAL::eprGetByte(EPR_FIL_SENSOR_ON);
|
||||
EEPROM::busesensor = HAL::eprGetByte(EPR_FIL_SENSOR_ON);
|
||||
#endif
|
||||
#if defined(TOP_SENSOR_PIN)
|
||||
EEPROM::btopsensor=HAL::eprGetByte(EPR_TOP_SENSOR_ON);
|
||||
EEPROM::btopsensor = HAL::eprGetByte(EPR_TOP_SENSOR_ON);
|
||||
#endif
|
||||
#if ENABLE_WIFI
|
||||
HAL::bwifion=HAL::eprGetByte(EPR_WIFI_ON);
|
||||
HAL::bwifion = HAL::eprGetByte(EPR_WIFI_ON);
|
||||
#endif
|
||||
#if FEATURE_BEEPER
|
||||
HAL::enablesound=HAL::eprGetByte(EPR_SOUND_ON);
|
||||
HAL::enablesound = HAL::eprGetByte(EPR_SOUND_ON);
|
||||
#endif
|
||||
#if UI_AUTOLIGHTOFF_AFTER >0
|
||||
EEPROM::timepowersaving = HAL::eprGetInt32(EPR_POWERSAVE_AFTER_TIME);
|
||||
//new value do reset time
|
||||
UIDisplay::ui_autolightoff_time=HAL::timeInMilliseconds()+EEPROM::timepowersaving;
|
||||
EEPROM::timepowersaving = HAL::eprGetInt32(EPR_POWERSAVE_AFTER_TIME);
|
||||
//new value do reset time
|
||||
UIDisplay::ui_autolightoff_time = HAL::timeInMilliseconds() + EEPROM::timepowersaving;
|
||||
#endif
|
||||
EEPROM::ftemp_ext_pla= HAL::eprGetFloat(EPR_TEMP_EXT_PLA);
|
||||
EEPROM::ftemp_ext_abs= HAL::eprGetFloat(EPR_TEMP_EXT_ABS);
|
||||
EEPROM::ftemp_bed_pla= HAL::eprGetFloat(EPR_TEMP_BED_PLA);
|
||||
EEPROM::ftemp_bed_abs= HAL::eprGetFloat(EPR_TEMP_BED_ABS);
|
||||
EEPROM::loading_feed_rate= HAL::eprGetFloat(EPR_LOAD_FEED_RATE);
|
||||
EEPROM::unloading_feed_rate= HAL::eprGetFloat(EPR_UNLOAD_FEED_RATE);
|
||||
EEPROM::unloading_loading_distance= HAL::eprGetFloat(EPR_UNLOAD_LOAD_DISTANCE);
|
||||
EEPROM::ftemp_ext_pla = HAL::eprGetFloat(EPR_TEMP_EXT_PLA);
|
||||
EEPROM::ftemp_ext_abs = HAL::eprGetFloat(EPR_TEMP_EXT_ABS);
|
||||
EEPROM::ftemp_bed_pla = HAL::eprGetFloat(EPR_TEMP_BED_PLA);
|
||||
EEPROM::ftemp_bed_abs = HAL::eprGetFloat(EPR_TEMP_BED_ABS);
|
||||
EEPROM::loading_feed_rate = HAL::eprGetFloat(EPR_LOAD_FEED_RATE);
|
||||
EEPROM::unloading_feed_rate = HAL::eprGetFloat(EPR_UNLOAD_FEED_RATE);
|
||||
EEPROM::unloading_loading_distance = HAL::eprGetFloat(EPR_UNLOAD_LOAD_DISTANCE);
|
||||
#if ENABLE_BACKLASH_COMPENSATION
|
||||
Printer::backlashX = HAL::eprGetFloat(EPR_BACKLASH_X);
|
||||
Printer::backlashY = HAL::eprGetFloat(EPR_BACKLASH_Y);
|
||||
Printer::backlashZ = HAL::eprGetFloat(EPR_BACKLASH_Z);
|
||||
#endif
|
||||
#if FEATURE_AUTOLEVEL
|
||||
if(version>2)
|
||||
if(version > 2)
|
||||
{
|
||||
float sum = 0;
|
||||
for(uint8_t i = 0; i < 9; i++)
|
||||
|
@ -748,49 +780,58 @@ EEPROM::unloading_loading_distance= HAL::eprGetFloat(EPR_UNLOAD_LOAD_DISTANCE);
|
|||
if(sum < 2.7 || sum > 3.3)
|
||||
Printer::resetTransformationMatrix(false);
|
||||
Printer::setAutolevelActive(HAL::eprGetByte(EPR_AUTOLEVEL_ACTIVE));
|
||||
Com::printArrayFLN(Com::tTransformationMatrix,Printer::autolevelTransformation, 9, 6);
|
||||
//Davinci Specific
|
||||
//remove garbage output
|
||||
//Com::printArrayFLN(Com::tTransformationMatrix,Printer::autolevelTransformation, 9, 6);
|
||||
}
|
||||
#endif
|
||||
#if MIXING_EXTRUDER
|
||||
readMixingRatios();
|
||||
#endif
|
||||
// now the extruder
|
||||
for(uint8_t i=0; i<NUM_EXTRUDER; i++)
|
||||
if(includeExtruder)
|
||||
{
|
||||
#if MIXING_EXTRUDER
|
||||
readMixingRatios();
|
||||
#endif
|
||||
// now the extruder
|
||||
for(uint8_t i = 0; i < NUM_EXTRUDER; i++)
|
||||
{
|
||||
#if FEATURE_WATCHDOG
|
||||
HAL::pingWatchdog();
|
||||
HAL::pingWatchdog();
|
||||
#endif // FEATURE_WATCHDOG
|
||||
|
||||
int o=i*EEPROM_EXTRUDER_LENGTH+EEPROM_EXTRUDER_OFFSET;
|
||||
Extruder *e = &extruder[i];
|
||||
e->stepsPerMM = HAL::eprGetFloat(o+EPR_EXTRUDER_STEPS_PER_MM);
|
||||
e->maxFeedrate = HAL::eprGetFloat(o+EPR_EXTRUDER_MAX_FEEDRATE);
|
||||
e->maxStartFeedrate = HAL::eprGetFloat(o+EPR_EXTRUDER_MAX_START_FEEDRATE);
|
||||
e->maxAcceleration = HAL::eprGetFloat(o+EPR_EXTRUDER_MAX_ACCELERATION);
|
||||
e->tempControl.heatManager = HAL::eprGetByte(o+EPR_EXTRUDER_HEAT_MANAGER);
|
||||
int o=i*EEPROM_EXTRUDER_LENGTH+EEPROM_EXTRUDER_OFFSET;
|
||||
Extruder *e = &extruder[i];
|
||||
e->stepsPerMM = HAL::eprGetFloat(o+EPR_EXTRUDER_STEPS_PER_MM);
|
||||
e->maxFeedrate = HAL::eprGetFloat(o+EPR_EXTRUDER_MAX_FEEDRATE);
|
||||
e->maxStartFeedrate = HAL::eprGetFloat(o+EPR_EXTRUDER_MAX_START_FEEDRATE);
|
||||
e->maxAcceleration = HAL::eprGetFloat(o+EPR_EXTRUDER_MAX_ACCELERATION);
|
||||
e->tempControl.heatManager = HAL::eprGetByte(o+EPR_EXTRUDER_HEAT_MANAGER);
|
||||
#if TEMP_PID
|
||||
e->tempControl.pidDriveMax = HAL::eprGetByte(o+EPR_EXTRUDER_DRIVE_MAX);
|
||||
e->tempControl.pidDriveMin = HAL::eprGetByte(o+EPR_EXTRUDER_DRIVE_MIN);
|
||||
e->tempControl.pidPGain = HAL::eprGetFloat(o+EPR_EXTRUDER_PID_PGAIN);
|
||||
e->tempControl.pidIGain = HAL::eprGetFloat(o+EPR_EXTRUDER_PID_IGAIN);
|
||||
e->tempControl.pidDGain = HAL::eprGetFloat(o+EPR_EXTRUDER_PID_DGAIN);
|
||||
e->tempControl.pidMax = HAL::eprGetByte(o+EPR_EXTRUDER_PID_MAX);
|
||||
e->tempControl.pidDriveMax = HAL::eprGetByte(o+EPR_EXTRUDER_DRIVE_MAX);
|
||||
e->tempControl.pidDriveMin = HAL::eprGetByte(o+EPR_EXTRUDER_DRIVE_MIN);
|
||||
e->tempControl.pidPGain = HAL::eprGetFloat(o+EPR_EXTRUDER_PID_PGAIN);
|
||||
e->tempControl.pidIGain = HAL::eprGetFloat(o+EPR_EXTRUDER_PID_IGAIN);
|
||||
e->tempControl.pidDGain = HAL::eprGetFloat(o+EPR_EXTRUDER_PID_DGAIN);
|
||||
e->tempControl.pidMax = HAL::eprGetByte(o+EPR_EXTRUDER_PID_MAX);
|
||||
#endif
|
||||
e->xOffset = HAL::eprGetInt32(o+EPR_EXTRUDER_X_OFFSET);
|
||||
e->yOffset = HAL::eprGetInt32(o+EPR_EXTRUDER_Y_OFFSET);
|
||||
e->watchPeriod = HAL::eprGetInt16(o+EPR_EXTRUDER_WATCH_PERIOD);
|
||||
e->xOffset = HAL::eprGetInt32(o+EPR_EXTRUDER_X_OFFSET);
|
||||
e->yOffset = HAL::eprGetInt32(o+EPR_EXTRUDER_Y_OFFSET);
|
||||
e->watchPeriod = HAL::eprGetInt16(o+EPR_EXTRUDER_WATCH_PERIOD);
|
||||
#if RETRACT_DURING_HEATUP
|
||||
e->waitRetractTemperature = HAL::eprGetInt16(o+EPR_EXTRUDER_WAIT_RETRACT_TEMP);
|
||||
e->waitRetractUnits = HAL::eprGetInt16(o+EPR_EXTRUDER_WAIT_RETRACT_UNITS);
|
||||
e->waitRetractTemperature = HAL::eprGetInt16(o+EPR_EXTRUDER_WAIT_RETRACT_TEMP);
|
||||
e->waitRetractUnits = HAL::eprGetInt16(o+EPR_EXTRUDER_WAIT_RETRACT_UNITS);
|
||||
#endif
|
||||
#if USE_ADVANCE
|
||||
#if ENABLE_QUADRATIC_ADVANCE
|
||||
e->advanceK = HAL::eprGetFloat(o+EPR_EXTRUDER_ADVANCE_K);
|
||||
e->advanceK = HAL::eprGetFloat(o+EPR_EXTRUDER_ADVANCE_K);
|
||||
#endif
|
||||
e->advanceL = HAL::eprGetFloat(o+EPR_EXTRUDER_ADVANCE_L);
|
||||
e->advanceL = HAL::eprGetFloat(o+EPR_EXTRUDER_ADVANCE_L);
|
||||
#endif
|
||||
if(version > 1)
|
||||
e->coolerSpeed = HAL::eprGetByte(o+EPR_EXTRUDER_COOLER_SPEED);
|
||||
if(version > 1)
|
||||
e->coolerSpeed = HAL::eprGetByte(o+EPR_EXTRUDER_COOLER_SPEED);
|
||||
if(version < 13) {
|
||||
HAL::eprSetInt32(o+EPR_EXTRUDER_Z_OFFSET,e->zOffset);
|
||||
}
|
||||
e->zOffset = HAL::eprGetInt32(o + EPR_EXTRUDER_Z_OFFSET);
|
||||
}
|
||||
}
|
||||
if(version != EEPROM_PROTOCOL_VERSION)
|
||||
{
|
||||
|
@ -808,23 +849,25 @@ EEPROM::unloading_loading_distance= HAL::eprGetFloat(EPR_UNLOAD_LOAD_DISTANCE);
|
|||
HAL::eprSetFloat(EPR_Z_PROBE_Y2,Z_PROBE_Y2);
|
||||
HAL::eprSetFloat(EPR_Z_PROBE_X3,Z_PROBE_X3);
|
||||
HAL::eprSetFloat(EPR_Z_PROBE_Y3,Z_PROBE_Y3);
|
||||
//Davinci Specific
|
||||
//Davinci Specific
|
||||
HAL::eprSetFloat(EPR_MANUAL_LEVEL_X1, MANUAL_LEVEL_X1);
|
||||
HAL::eprSetFloat(EPR_MANUAL_LEVEL_Y1, MANUAL_LEVEL_Y1);
|
||||
HAL::eprSetFloat(EPR_MANUAL_LEVEL_X2, MANUAL_LEVEL_X2);
|
||||
HAL::eprSetFloat(EPR_MANUAL_LEVEL_Y2, MANUAL_LEVEL_Y2);
|
||||
HAL::eprSetFloat(EPR_MANUAL_LEVEL_X3, MANUAL_LEVEL_X3);
|
||||
HAL::eprSetFloat(EPR_MANUAL_LEVEL_Y3, MANUAL_LEVEL_Y3);
|
||||
HAL::eprSetFloat(EPR_MANUAL_LEVEL_X4, MANUAL_LEVEL_X4);
|
||||
HAL::eprSetFloat(EPR_MANUAL_LEVEL_Y4, MANUAL_LEVEL_Y4);
|
||||
HAL::eprSetFloat(EPR_MANUAL_LEVEL_Y1, MANUAL_LEVEL_Y1);
|
||||
HAL::eprSetFloat(EPR_MANUAL_LEVEL_X2, MANUAL_LEVEL_X2);
|
||||
HAL::eprSetFloat(EPR_MANUAL_LEVEL_Y2, MANUAL_LEVEL_Y2);
|
||||
HAL::eprSetFloat(EPR_MANUAL_LEVEL_X3, MANUAL_LEVEL_X3);
|
||||
HAL::eprSetFloat(EPR_MANUAL_LEVEL_Y3, MANUAL_LEVEL_Y3);
|
||||
HAL::eprSetFloat(EPR_MANUAL_LEVEL_X4, MANUAL_LEVEL_X4);
|
||||
HAL::eprSetFloat(EPR_MANUAL_LEVEL_Y4, MANUAL_LEVEL_Y4);
|
||||
}
|
||||
if(version < 4)
|
||||
{
|
||||
#if NONLINEAR_SYSTEM
|
||||
HAL::eprSetInt16(EPR_DELTA_SEGMENTS_PER_SECOND_PRINT,DELTA_SEGMENTS_PER_SECOND_PRINT);
|
||||
HAL::eprSetInt16(EPR_DELTA_SEGMENTS_PER_SECOND_MOVE,DELTA_SEGMENTS_PER_SECOND_MOVE);
|
||||
#endif
|
||||
#if DRIVE_SYSTEM == DELTA
|
||||
HAL::eprSetFloat(EPR_DELTA_DIAGONAL_ROD_LENGTH,DELTA_DIAGONAL_ROD);
|
||||
HAL::eprSetFloat(EPR_DELTA_HORIZONTAL_RADIUS,ROD_RADIUS);
|
||||
HAL::eprSetInt16(EPR_DELTA_SEGMENTS_PER_SECOND_PRINT,DELTA_SEGMENTS_PER_SECOND_PRINT);
|
||||
HAL::eprSetInt16(EPR_DELTA_SEGMENTS_PER_SECOND_MOVE,DELTA_SEGMENTS_PER_SECOND_MOVE);
|
||||
HAL::eprSetInt16(EPR_DELTA_TOWERX_OFFSET_STEPS,DELTA_X_ENDSTOP_OFFSET_STEPS);
|
||||
HAL::eprSetInt16(EPR_DELTA_TOWERY_OFFSET_STEPS,DELTA_Y_ENDSTOP_OFFSET_STEPS);
|
||||
HAL::eprSetInt16(EPR_DELTA_TOWERZ_OFFSET_STEPS,DELTA_Z_ENDSTOP_OFFSET_STEPS);
|
||||
|
@ -882,6 +925,21 @@ EEPROM::unloading_loading_distance= HAL::eprGetFloat(EPR_UNLOAD_LOAD_DISTANCE);
|
|||
HAL::eprSetFloat(EPR_RETRACTION_UNDO_SPEED,RETRACTION_UNDO_SPEED);
|
||||
HAL::eprSetByte(EPR_AUTORETRACT_ENABLED,AUTORETRACT_ENABLED);
|
||||
}
|
||||
if(version < 14) {
|
||||
HAL::eprSetFloat(EPR_Z_PROBE_Z_OFFSET,Z_PROBE_Z_OFFSET);
|
||||
}
|
||||
if(version < 15) {
|
||||
HAL::eprSetByte(EPR_SELECTED_LANGUAGE, 254); // activate selector on startup
|
||||
#if UI_DISPLAY_TYPE != NO_DISPLAY
|
||||
Com::selectedLanguage = 254;
|
||||
#endif
|
||||
}
|
||||
if(version < 16) {
|
||||
HAL::eprSetFloat(EPR_BENDING_CORRECTION_A,BENDING_CORRECTION_A);
|
||||
HAL::eprSetFloat(EPR_BENDING_CORRECTION_B,BENDING_CORRECTION_B);
|
||||
HAL::eprSetFloat(EPR_BENDING_CORRECTION_C,BENDING_CORRECTION_C);
|
||||
HAL::eprSetFloat(EPR_ACCELERATION_FACTOR_TOP,ACCELERATION_FACTOR_TOP);
|
||||
}
|
||||
/* if (version<8) {
|
||||
#if DRIVE_SYSTEM==DELTA
|
||||
// Prior to verion 8, the cartesian max was stored in the zmax
|
||||
|
@ -900,6 +958,10 @@ EEPROM::unloading_loading_distance= HAL::eprGetFloat(EPR_UNLOAD_LOAD_DISTANCE);
|
|||
|
||||
storeDataIntoEEPROM(false); // Store new fields for changed version
|
||||
}
|
||||
Printer::zBedOffset = HAL::eprGetFloat(EPR_Z_PROBE_Z_OFFSET);
|
||||
#if UI_DISPLAY_TYPE != NO_DISPLAY
|
||||
Com::selectLanguage(HAL::eprGetByte(EPR_SELECTED_LANGUAGE));
|
||||
#endif
|
||||
Printer::updateDerivedParameter();
|
||||
Extruder::initHeatedBed();
|
||||
#endif
|
||||
|
@ -907,10 +969,10 @@ EEPROM::unloading_loading_distance= HAL::eprGetFloat(EPR_UNLOAD_LOAD_DISTANCE);
|
|||
|
||||
void EEPROM::initBaudrate()
|
||||
{
|
||||
// Invariant - baudrate is intitalized with or without eeprom!
|
||||
// Invariant - baudrate is initialized with or without eeprom!
|
||||
baudrate = BAUDRATE;
|
||||
#if EEPROM_MODE != 0
|
||||
if(HAL::eprGetByte(EPR_MAGIC_BYTE)==EEPROM_MODE)
|
||||
if(HAL::eprGetByte(EPR_MAGIC_BYTE) == EEPROM_MODE)
|
||||
{
|
||||
baudrate = HAL::eprGetInt32(EPR_BAUDRATE);
|
||||
}
|
||||
|
@ -927,7 +989,7 @@ void EEPROM::init()
|
|||
uint8_t storedcheck = HAL::eprGetByte(EPR_INTEGRITY_BYTE);
|
||||
if(HAL::eprGetByte(EPR_MAGIC_BYTE) == EEPROM_MODE && storedcheck == check)
|
||||
{
|
||||
readDataFromEEPROM();
|
||||
readDataFromEEPROM(true);
|
||||
if (USE_CONFIGURATION_BAUD_RATE)
|
||||
{
|
||||
// Used if eeprom gets unusable baud rate set and communication wont work at all.
|
||||
|
@ -939,13 +1001,13 @@ void EEPROM::init()
|
|||
if(newcheck != HAL::eprGetByte(EPR_INTEGRITY_BYTE))
|
||||
HAL::eprSetByte(EPR_INTEGRITY_BYTE,newcheck);
|
||||
}
|
||||
Com::printFLN(PSTR("EEprom baud rate restored from configuration."));
|
||||
Com::printFLN(PSTR("EEPROM baud rate restored from configuration."));
|
||||
Com::printFLN(PSTR("RECOMPILE WITH USE_CONFIGURATION_BAUD_RATE == 0 to alter baud rate via EEPROM"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
HAL::eprSetByte(EPR_MAGIC_BYTE,EEPROM_MODE); // Make datachange permanent
|
||||
HAL::eprSetByte(EPR_MAGIC_BYTE,EEPROM_MODE); // Make data change permanent
|
||||
initalizeUncached();
|
||||
storeDataIntoEEPROM(storedcheck != check);
|
||||
}
|
||||
|
@ -982,6 +1044,7 @@ With
|
|||
void EEPROM::writeSettings()
|
||||
{
|
||||
#if EEPROM_MODE != 0
|
||||
writeByte(EPR_SELECTED_LANGUAGE,Com::tLanguage);
|
||||
writeLong(EPR_BAUDRATE, Com::tEPRBaudrate);
|
||||
//Davinci Specific
|
||||
writeByte(EPR_DISPLAY_MODE, Com::tDisplayMode);
|
||||
|
@ -993,10 +1056,10 @@ void EEPROM::writeSettings()
|
|||
writeByte(EPR_BADGE_LIGHT_ON,Com::tBadgeLightOn);
|
||||
#endif
|
||||
#if defined(FIL_SENSOR1_PIN)
|
||||
writeByte(EPR_FIL_SENSOR_ON,Com::tSensorOn);
|
||||
writeByte(EPR_FIL_SENSOR_ON,Com::tSensorOn);
|
||||
#endif
|
||||
#if defined(TOP_SENSOR_PIN)
|
||||
writeByte(EPR_TOP_SENSOR_ON,Com::tTopsensorOn);
|
||||
writeByte(EPR_TOP_SENSOR_ON,Com::tTopsensorOn);
|
||||
#endif
|
||||
#if FEATURE_BEEPER
|
||||
writeByte(EPR_SOUND_ON,Com::tSoundOn);
|
||||
|
@ -1009,8 +1072,8 @@ void EEPROM::writeSettings()
|
|||
writeLong(EPR_MAX_INACTIVE_TIME, Com::tEPRMaxInactiveTime);
|
||||
writeLong(EPR_STEPPER_INACTIVE_TIME, Com::tEPRStopAfterInactivty);
|
||||
//Davinci Specific
|
||||
#if UI_AUTOLIGHTOFF_AFTER !=0
|
||||
writeLong(EPR_POWERSAVE_AFTER_TIME,Com::tPowerSave);
|
||||
#if UI_AUTOLIGHTOFF_AFTER != 0
|
||||
writeLong(EPR_POWERSAVE_AFTER_TIME,Com::tPowerSave);
|
||||
#endif
|
||||
writeFloat(EPR_TEMP_EXT_PLA,Com::tTempExtPLA);
|
||||
writeFloat(EPR_TEMP_EXT_ABS,Com::tTempExtABS);
|
||||
|
@ -1050,7 +1113,10 @@ void EEPROM::writeSettings()
|
|||
writeFloat(EPR_BACKLASH_Y, Com::tEPRYBacklash);
|
||||
writeFloat(EPR_BACKLASH_Z, Com::tEPRZBacklash);
|
||||
#endif
|
||||
|
||||
#if NONLINEAR_SYSTEM
|
||||
writeInt(EPR_DELTA_SEGMENTS_PER_SECOND_MOVE, Com::tEPRSegmentsPerSecondTravel);
|
||||
writeInt(EPR_DELTA_SEGMENTS_PER_SECOND_PRINT, Com::tEPRSegmentsPerSecondPrint);
|
||||
#endif
|
||||
#if RAMP_ACCELERATION
|
||||
//epr_out_float(EPR_X_MAX_START_SPEED,PSTR("X-axis start speed [mm/s]"));
|
||||
//epr_out_float(EPR_Y_MAX_START_SPEED,PSTR("Y-axis start speed [mm/s]"));
|
||||
|
@ -1061,11 +1127,12 @@ void EEPROM::writeSettings()
|
|||
#if DRIVE_SYSTEM == DELTA
|
||||
writeFloat(EPR_Z_MAX_ACCEL, Com::tEPRZAcceleration);
|
||||
writeFloat(EPR_Z_MAX_TRAVEL_ACCEL, Com::tEPRZTravelAcceleration);
|
||||
#if defined(INTERPOLATE_ACCELERATION_WITH_Z) && INTERPOLATE_ACCELERATION_WITH_Z != 0
|
||||
writeFloat(EPR_ACCELERATION_FACTOR_TOP, Com::tEPRAccelerationFactorAtTop);
|
||||
#endif
|
||||
writeFloat(EPR_DELTA_DIAGONAL_ROD_LENGTH, Com::tEPRDiagonalRodLength);
|
||||
writeFloat(EPR_DELTA_HORIZONTAL_RADIUS, Com::tEPRHorizontalRadius);
|
||||
writeFloat(EPR_DELTA_MAX_RADIUS, Com::tEPRDeltaMaxRadius);
|
||||
writeInt(EPR_DELTA_SEGMENTS_PER_SECOND_MOVE, Com::tEPRSegmentsPerSecondTravel);
|
||||
writeInt(EPR_DELTA_SEGMENTS_PER_SECOND_PRINT, Com::tEPRSegmentsPerSecondPrint);
|
||||
writeInt(EPR_DELTA_TOWERX_OFFSET_STEPS, Com::tEPRTowerXOffset);
|
||||
writeInt(EPR_DELTA_TOWERY_OFFSET_STEPS, Com::tEPRTowerYOffset);
|
||||
writeInt(EPR_DELTA_TOWERZ_OFFSET_STEPS, Com::tEPRTowerZOffset);
|
||||
|
@ -1085,17 +1152,21 @@ void EEPROM::writeSettings()
|
|||
writeFloat(EPR_X_MAX_TRAVEL_ACCEL, Com::tEPRXTravelAcceleration);
|
||||
writeFloat(EPR_Y_MAX_TRAVEL_ACCEL, Com::tEPRYTravelAcceleration);
|
||||
writeFloat(EPR_Z_MAX_TRAVEL_ACCEL, Com::tEPRZTravelAcceleration);
|
||||
#if defined(INTERPOLATE_ACCELERATION_WITH_Z) && INTERPOLATE_ACCELERATION_WITH_Z != 0
|
||||
writeFloat(EPR_ACCELERATION_FACTOR_TOP, Com::tEPRAccelerationFactorAtTop);
|
||||
#endif
|
||||
#endif
|
||||
//Davinci Specific
|
||||
writeFloat(EPR_MANUAL_LEVEL_X1, Com::tManualProbeX1);
|
||||
writeFloat(EPR_MANUAL_LEVEL_Y1, Com::tManualProbeY1);
|
||||
writeFloat(EPR_MANUAL_LEVEL_X2, Com::tManualProbeX2);
|
||||
writeFloat(EPR_MANUAL_LEVEL_Y2, Com::tManualProbeY2);
|
||||
writeFloat(EPR_MANUAL_LEVEL_X3, Com::tManualProbeX3);
|
||||
writeFloat(EPR_MANUAL_LEVEL_Y3, Com::tManualProbeY3);
|
||||
writeFloat(EPR_MANUAL_LEVEL_X4, Com::tManualProbeX4);
|
||||
writeFloat(EPR_MANUAL_LEVEL_Y4, Com::tManualProbeY4);
|
||||
#endif
|
||||
writeFloat(EPR_Z_PROBE_Z_OFFSET, Com::tZProbeOffsetZ);
|
||||
//Davinci Specific
|
||||
writeFloat(EPR_MANUAL_LEVEL_X1, Com::tManualProbeX1);
|
||||
writeFloat(EPR_MANUAL_LEVEL_Y1, Com::tManualProbeY1);
|
||||
writeFloat(EPR_MANUAL_LEVEL_X2, Com::tManualProbeX2);
|
||||
writeFloat(EPR_MANUAL_LEVEL_Y2, Com::tManualProbeY2);
|
||||
writeFloat(EPR_MANUAL_LEVEL_X3, Com::tManualProbeX3);
|
||||
writeFloat(EPR_MANUAL_LEVEL_Y3, Com::tManualProbeY3);
|
||||
writeFloat(EPR_MANUAL_LEVEL_X4, Com::tManualProbeX4);
|
||||
writeFloat(EPR_MANUAL_LEVEL_Y4, Com::tManualProbeY4);
|
||||
#if FEATURE_Z_PROBE
|
||||
writeFloat(EPR_Z_PROBE_HEIGHT, Com::tZProbeHeight);
|
||||
writeFloat(EPR_Z_PROBE_BED_DISTANCE, Com::tZProbeBedDitance);
|
||||
|
@ -1109,15 +1180,18 @@ void EEPROM::writeSettings()
|
|||
writeFloat(EPR_Z_PROBE_Y2, Com::tZProbeY2);
|
||||
writeFloat(EPR_Z_PROBE_X3, Com::tZProbeX3);
|
||||
writeFloat(EPR_Z_PROBE_Y3, Com::tZProbeY3);
|
||||
writeFloat(EPR_BENDING_CORRECTION_A, Com::zZProbeBendingCorA);
|
||||
writeFloat(EPR_BENDING_CORRECTION_B, Com::zZProbeBendingCorB);
|
||||
writeFloat(EPR_BENDING_CORRECTION_C, Com::zZProbeBendingCorC);
|
||||
#endif
|
||||
#if FEATURE_AUTOLEVEL
|
||||
writeByte(EPR_AUTOLEVEL_ACTIVE, Com::tAutolevelActive);
|
||||
#endif
|
||||
|
||||
#if FEATURE_AXISCOMP
|
||||
writeFloat(EPR_AXISCOMP_TANXY, Com::tAxisCompTanXY);
|
||||
writeFloat(EPR_AXISCOMP_TANYZ, Com::tAxisCompTanYZ);
|
||||
writeFloat(EPR_AXISCOMP_TANXZ, Com::tAxisCompTanXZ);
|
||||
writeFloat(EPR_AXISCOMP_TANXY, Com::tAxisCompTanXY,6);
|
||||
writeFloat(EPR_AXISCOMP_TANYZ, Com::tAxisCompTanYZ,6);
|
||||
writeFloat(EPR_AXISCOMP_TANXZ, Com::tAxisCompTanXZ,6);
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -1165,6 +1239,7 @@ void EEPROM::writeSettings()
|
|||
#endif
|
||||
writeLong(o + EPR_EXTRUDER_X_OFFSET, Com::tEPRXOffset);
|
||||
writeLong(o + EPR_EXTRUDER_Y_OFFSET, Com::tEPRYOffset);
|
||||
writeLong(o + EPR_EXTRUDER_Z_OFFSET, Com::tEPRZOffset);
|
||||
writeInt(o + EPR_EXTRUDER_WATCH_PERIOD, Com::tEPRStabilizeTime);
|
||||
#if RETRACT_DURING_HEATUP
|
||||
writeInt(o + EPR_EXTRUDER_WAIT_RETRACT_TEMP, Com::tEPRRetractionWhenHeating);
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#define _EEPROM_H
|
||||
|
||||
// Id to distinguish version changes
|
||||
#define EEPROM_PROTOCOL_VERSION 12
|
||||
#define EEPROM_PROTOCOL_VERSION 16
|
||||
|
||||
/** Where to start with our datablock in memory. Can be moved if you
|
||||
have problems with other modules using the eeprom */
|
||||
|
@ -112,15 +112,21 @@ have problems with other modules using the eeprom */
|
|||
#define EPR_AXISCOMP_TANYZ 980
|
||||
#define EPR_AXISCOMP_TANXZ 984
|
||||
|
||||
#define EPR_DISTORTION_CORRECTION_ENABLED 988
|
||||
#define EPR_RETRACTION_LENGTH 992
|
||||
#define EPR_RETRACTION_LONG_LENGTH 996
|
||||
#define EPR_RETRACTION_SPEED 1000
|
||||
#define EPR_RETRACTION_Z_LIFT 1004
|
||||
#define EPR_RETRACTION_UNDO_EXTRA_LENGTH 1008
|
||||
#define EPR_DISTORTION_CORRECTION_ENABLED 988
|
||||
#define EPR_RETRACTION_LENGTH 992
|
||||
#define EPR_RETRACTION_LONG_LENGTH 996
|
||||
#define EPR_RETRACTION_SPEED 1000
|
||||
#define EPR_RETRACTION_Z_LIFT 1004
|
||||
#define EPR_RETRACTION_UNDO_EXTRA_LENGTH 1008
|
||||
#define EPR_RETRACTION_UNDO_EXTRA_LONG_LENGTH 1012
|
||||
#define EPR_RETRACTION_UNDO_SPEED 1016
|
||||
#define EPR_AUTORETRACT_ENABLED 1020
|
||||
#define EPR_RETRACTION_UNDO_SPEED 1016
|
||||
#define EPR_AUTORETRACT_ENABLED 1020
|
||||
#define EPR_Z_PROBE_Z_OFFSET 1024
|
||||
#define EPR_SELECTED_LANGUAGE 1028
|
||||
#define EPR_ACCELERATION_FACTOR_TOP 1032
|
||||
#define EPR_BENDING_CORRECTION_A 1036
|
||||
#define EPR_BENDING_CORRECTION_B 1040
|
||||
#define EPR_BENDING_CORRECTION_C 1044
|
||||
|
||||
//Davinci Specific
|
||||
#define EPR_LIGHT_ON 1119
|
||||
|
@ -154,9 +160,9 @@ have problems with other modules using the eeprom */
|
|||
#define EEPROM_BYTE(x) HAL::eprGetByte(EPR_##x)
|
||||
#define EEPROM_SET_BYTE(x,val) HAL::eprSetByte(EPR_##x,val)
|
||||
#else
|
||||
#define EEPROM_FLOAT(x) (x)
|
||||
#define EEPROM_INT32(x) (x)
|
||||
#define EEPROM_BYTE(x) (x)
|
||||
#define EEPROM_FLOAT(x) (float)(x)
|
||||
#define EEPROM_INT32(x) (int32_t)(x)
|
||||
#define EEPROM_BYTE(x) (uint8_t)(x)
|
||||
#define EEPROM_SET_BYTE(x,val)
|
||||
#endif
|
||||
|
||||
|
@ -188,6 +194,7 @@ have problems with other modules using the eeprom */
|
|||
#define EPR_EXTRUDER_COOLER_SPEED 54
|
||||
// 55-57 free for byte sized parameter
|
||||
#define EPR_EXTRUDER_MIXING_RATIOS 58 // 16*2 byte ratios = 32 byte -> end = 89
|
||||
#define EPR_EXTRUDER_Z_OFFSET 90
|
||||
#ifndef Z_PROBE_BED_DISTANCE
|
||||
#define Z_PROBE_BED_DISTANCE 5.0
|
||||
#endif
|
||||
|
@ -203,7 +210,7 @@ class EEPROM
|
|||
{
|
||||
#if EEPROM_MODE != 0
|
||||
static void writeExtruderPrefix(uint pos);
|
||||
static void writeFloat(uint pos,PGM_P text,uint8_t digits=3);
|
||||
static void writeFloat(uint pos,PGM_P text,uint8_t digits = 3);
|
||||
static void writeLong(uint pos,PGM_P text);
|
||||
static void writeInt(uint pos,PGM_P text);
|
||||
static void writeByte(uint pos,PGM_P text);
|
||||
|
@ -216,6 +223,9 @@ public:
|
|||
static void init();
|
||||
static void initBaudrate();
|
||||
//Davinci Specific
|
||||
#if DAVINCI == 4
|
||||
static float rotate_speed;
|
||||
#endif
|
||||
static bool buselight;
|
||||
static bool busebadgelight;
|
||||
static bool busesensor;
|
||||
|
@ -229,15 +239,34 @@ public:
|
|||
static float loading_feed_rate;
|
||||
static float unloading_feed_rate;
|
||||
static float unloading_loading_distance;
|
||||
static void storeDataIntoEEPROM(uint8_t corrupted=0);
|
||||
static void readDataFromEEPROM();
|
||||
static void storeDataIntoEEPROM(uint8_t corrupted = 0);
|
||||
static void readDataFromEEPROM(bool includeExtruder);
|
||||
static void restoreEEPROMSettingsFromConfiguration();
|
||||
static void writeSettings();
|
||||
static void update(GCode *com);
|
||||
//Davinci Specific, for internal update
|
||||
static void update(long P,uint8_t T,long S,float X);
|
||||
static void updatePrinterUsage();
|
||||
|
||||
static inline void setVersion(uint8_t v) {
|
||||
#if EEPROM_MODE != 0
|
||||
HAL::eprSetByte(EPR_VERSION,v);
|
||||
HAL::eprSetByte(EPR_INTEGRITY_BYTE,computeChecksum());
|
||||
#endif
|
||||
}
|
||||
static inline uint8_t getStoredLanguage() {
|
||||
#if EEPROM_MODE != 0
|
||||
return HAL::eprGetByte(EPR_SELECTED_LANGUAGE);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
static inline float zProbeZOffset() {
|
||||
#if EEPROM_MODE != 0
|
||||
return HAL::eprGetFloat(EPR_Z_PROBE_Z_OFFSET);
|
||||
#else
|
||||
return Z_PROBE_Z_OFFSET;
|
||||
#endif
|
||||
}
|
||||
static inline float zProbeSpeed() {
|
||||
#if EEPROM_MODE != 0
|
||||
return HAL::eprGetFloat(EPR_Z_PROBE_SPEED);
|
||||
|
@ -628,5 +657,34 @@ static inline void setTowerZFloor(float newZ) {
|
|||
return 0;
|
||||
#endif
|
||||
}
|
||||
static inline float bendingCorrectionA() {
|
||||
#if EEPROM_MODE != 0
|
||||
return HAL::eprGetFloat(EPR_BENDING_CORRECTION_A);
|
||||
#else
|
||||
return BENDING_CORRECTION_A;
|
||||
#endif
|
||||
}
|
||||
static inline float bendingCorrectionB() {
|
||||
#if EEPROM_MODE != 0
|
||||
return HAL::eprGetFloat(EPR_BENDING_CORRECTION_B);
|
||||
#else
|
||||
return BENDING_CORRECTION_B;
|
||||
#endif
|
||||
}
|
||||
static inline float bendingCorrectionC() {
|
||||
#if EEPROM_MODE != 0
|
||||
return HAL::eprGetFloat(EPR_BENDING_CORRECTION_C);
|
||||
#else
|
||||
return BENDING_CORRECTION_C;
|
||||
#endif
|
||||
}
|
||||
static inline float accelarationFactorTop() {
|
||||
#if EEPROM_MODE != 0
|
||||
return HAL::eprGetFloat(EPR_ACCELERATION_FACTOR_TOP);
|
||||
#else
|
||||
return ACCELERATION_FACTOR_TOP;
|
||||
#endif
|
||||
}
|
||||
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
#ifndef EVENTS_H_INCLUDED
|
||||
#define EVENTS_H_INCLUDED
|
||||
|
||||
/*
|
||||
Event system in a nutshell:
|
||||
|
||||
All printers are different and my need additions in th eone or other place.
|
||||
It is not very convenient to add these code parts across the firmware. For this
|
||||
reason repetier-firmware uses a simple event system that comes at no cost if
|
||||
a event is not used.
|
||||
|
||||
- simple: Only one subscriber is possible
|
||||
- cost effective: Macros work as event caller. By default all macros are empty
|
||||
|
||||
How to use the system:
|
||||
|
||||
1. In Configuration.h add
|
||||
#define CUSTOM_EVENTS
|
||||
2. Add a file "CustomEvents.h" which overrides all event macros you need.
|
||||
It shoudl also include the function declarations used.
|
||||
3. Add a file "CustomEventsImpl.h" which includes all function definitions.
|
||||
Also it is named .h it will be included inside a cpp file only once.
|
||||
This is to compile only when selected and still keep ArduinoIDE happy.
|
||||
|
||||
Each of the following events describe the parameter and when it is called.
|
||||
*/
|
||||
|
||||
// Catch heating events. id is extruder id or -1 for heated bed.
|
||||
#define EVENT_WAITING_HEATER(id) {}
|
||||
#define EVENT_HEATING_FINISHED(id) {}
|
||||
|
||||
// This gets called every 0.1 second
|
||||
#define EVENT_TIMER_100MS {}
|
||||
// This gets called every 0.5 second
|
||||
#define EVENT_TIMER_500MS {}
|
||||
// Gets called on a regular basis as time allows
|
||||
#define EVENT_PERIODICAL {}
|
||||
// Gets called when kill gets called. only_steppes = true -> we only want to disable steppers, not everything.
|
||||
#define EVENT_KILL(only_steppers) {}
|
||||
// Gets called when a jam was detected.
|
||||
#define EVENT_JAM_DETECTED {}
|
||||
// Gets called every time the jam detection signal switches. Steps are the extruder steps since last change.
|
||||
#define EVENT_JAM_SIGNAL_CHANGED(extruderId,steps) {}
|
||||
// Gets called if a heater decoupling is detected.
|
||||
#define EVENT_HEATER_DECOUPLED(id) {}
|
||||
// Gets called if a missing/shorted thermistor is detected.
|
||||
#define EVENT_HEATER_DEFECT(id) {}
|
||||
// Gets called if a action in ui.cpp okAction gets executed.
|
||||
#define EVENT_START_UI_ACTION(shortAction) {}
|
||||
// Gets called if a nextPrevius actions gets executed.
|
||||
#define EVENT_START_NEXTPREVIOUS(action,increment) {}
|
||||
// Gets called before a move is queued. Gives the ability to limit moves.
|
||||
#define EVENT_CONTRAIN_DESTINATION_COORDINATES
|
||||
// Gets called when a fatal error occurs and all actions should be stopped
|
||||
#define EVENT_FATAL_ERROR_OCCURED
|
||||
// Gets called after a M999 to continue from fatal errors
|
||||
#define EVENT_CONTINUE_FROM_FATAL_ERROR
|
||||
|
||||
// Called to initialize laser pins. Return false to prevent default initialization.
|
||||
#define EVENT_INITALIZE_LASER true
|
||||
// Set laser to intensity level 0 = off, 255 = full. Return false if you have overridden the setting routine.
|
||||
// with true the default solution will set it as digital value.
|
||||
#define EVENT_SET_LASER(intensity) true
|
||||
|
||||
// Called to initialize CNC pins. Return false to prevent default initialization.
|
||||
#define EVENT_INITALIZE_CNC true
|
||||
// Turn off spindle
|
||||
#define EVENT_SPINDLE_OFF true
|
||||
// Turn spindle clockwise
|
||||
#define EVENT_SPINDLE_CW(rpm) true
|
||||
// Turn spindle counter clockwise
|
||||
#define EVENT_SPINDLE_CCW(rpm) true
|
||||
|
||||
// Allow adding new G and M codes. To implement it create a function
|
||||
// bool eventUnhandledGCode(GCode *com)
|
||||
// that returns true if it handled the code, otherwise false.
|
||||
// Event define would then be
|
||||
// #define EVENT_UNHANDLED_G_CODE(c) eventUnhandledGCode(c)
|
||||
#define EVENT_UNHANDLED_G_CODE(c) false
|
||||
#define EVENT_UNHANDLED_M_CODE(c) false
|
||||
|
||||
// Called when bed temperature is set
|
||||
#define EVENT_SET_BED_TEMP(temp,boop)
|
||||
|
||||
// This gets called every time the user has saved a value to eeprom
|
||||
// or any other reason why dependent values may need recomputation.
|
||||
#define EVENT_UPDATE_DERIVED {}
|
||||
|
||||
// This gets called after the basic firmware functions have initialized.
|
||||
// Use this to initalize your hardware etc.
|
||||
#define EVENT_INITIALIZE {}
|
||||
|
||||
#endif // EVENTS_H_INCLUDED
|
Plik diff jest za duży
Load Diff
|
@ -9,7 +9,7 @@
|
|||
//#endif
|
||||
|
||||
// Updates the temperature of all extruders and heated bed if it's time.
|
||||
// Toggels the heater power if necessary.
|
||||
// Toggles the heater power if necessary.
|
||||
extern bool reportTempsensorError(); ///< Report defect sensors
|
||||
extern uint8_t manageMonitor;
|
||||
#define HTR_OFF 0
|
||||
|
@ -18,14 +18,15 @@ extern uint8_t manageMonitor;
|
|||
#define HTR_DEADTIME 3
|
||||
|
||||
#define TEMPERATURE_CONTROLLER_FLAG_ALARM 1
|
||||
#define TEMPERATURE_CONTROLLER_FLAG_DECOUPLE_FULL 2 //< Full heating enabled
|
||||
#define TEMPERATURE_CONTROLLER_FLAG_DECOUPLE_HOLD 4 //< Holding target temperature
|
||||
#define TEMPERATURE_CONTROLLER_FLAG_SENSDEFECT 8 //< Indicating sensor defect
|
||||
#define TEMPERATURE_CONTROLLER_FLAG_SENSDECOUPLED 16 //< Indicating sensor decoupling
|
||||
#define TEMPERATURE_CONTROLLER_FLAG_JAM 32 //< Indicates a jammed filament
|
||||
#define TEMPERATURE_CONTROLLER_FLAG_SLOWDOWN 64 //< Indicates a slowed down extruder
|
||||
#define TEMPERATURE_CONTROLLER_FLAG_DECOUPLE_FULL 2 ///< Full heating enabled
|
||||
#define TEMPERATURE_CONTROLLER_FLAG_DECOUPLE_HOLD 4 ///< Holding target temperature
|
||||
#define TEMPERATURE_CONTROLLER_FLAG_SENSDEFECT 8 ///< Indicating sensor defect
|
||||
#define TEMPERATURE_CONTROLLER_FLAG_SENSDECOUPLED 16 ///< Indicating sensor decoupling
|
||||
#define TEMPERATURE_CONTROLLER_FLAG_JAM 32 ///< Indicates a jammed filament
|
||||
#define TEMPERATURE_CONTROLLER_FLAG_SLOWDOWN 64 ///< Indicates a slowed down extruder
|
||||
#define TEMPERATURE_CONTROLLER_FLAG_FILAMENTCHANGE 128 ///< Indicates we are switching filament
|
||||
|
||||
/** TemperatureController manages one heater-temperature sensore loop. You can have up to
|
||||
/** TemperatureController manages one heater-temperature sensor loop. You can have up to
|
||||
4 loops allowing pid/bang bang for up to 3 extruder and the heated bed.
|
||||
|
||||
*/
|
||||
|
@ -35,12 +36,12 @@ public:
|
|||
uint8_t pwmIndex; ///< pwm index for output control. 0-2 = Extruder, 3 = Fan, 4 = Heated Bed
|
||||
uint8_t sensorType; ///< Type of temperature sensor.
|
||||
uint8_t sensorPin; ///< Pin to read extruder temperature.
|
||||
int16_t currentTemperature; ///< Currenttemperature value read from sensor.
|
||||
int16_t targetTemperature; ///< Target temperature value in units of sensor.
|
||||
int8_t heatManager; ///< How is temperature controlled. 0 = on/off, 1 = PID-Control, 3 = dead time control
|
||||
int16_t currentTemperature; ///< Current temperature value read from sensor.
|
||||
//int16_t targetTemperature; ///< Target temperature value in units of sensor.
|
||||
float currentTemperatureC; ///< Current temperature in degC.
|
||||
float targetTemperatureC; ///< Target temperature in degC.
|
||||
uint32_t lastTemperatureUpdate; ///< Time in millis of the last temperature update.
|
||||
int8_t heatManager; ///< How is temperature controled. 0 = on/off, 1 = PID-Control, 3 = deat time control
|
||||
#if TEMP_PID
|
||||
float tempIState; ///< Temp. var. for PID computation.
|
||||
uint8_t pidDriveMax; ///< Used for windup in PID calculation.
|
||||
|
@ -82,6 +83,9 @@ public:
|
|||
{
|
||||
return flags & TEMPERATURE_CONTROLLER_FLAG_DECOUPLE_FULL;
|
||||
}
|
||||
inline void removeErrorStates() {
|
||||
flags &= ~(TEMPERATURE_CONTROLLER_FLAG_ALARM | TEMPERATURE_CONTROLLER_FLAG_SENSDEFECT | TEMPERATURE_CONTROLLER_FLAG_SENSDECOUPLED);
|
||||
}
|
||||
inline bool isDecoupleFullOrHold()
|
||||
{
|
||||
return flags & (TEMPERATURE_CONTROLLER_FLAG_DECOUPLE_FULL | TEMPERATURE_CONTROLLER_FLAG_DECOUPLE_HOLD);
|
||||
|
@ -131,16 +135,27 @@ public:
|
|||
return flags & TEMPERATURE_CONTROLLER_FLAG_SENSDECOUPLED;
|
||||
}
|
||||
#endif //FEATURE_DECOUPLE_TEST
|
||||
#if EXTRUDER_JAM_CONTROL
|
||||
inline bool isJammed()
|
||||
static void resetAllErrorStates();
|
||||
fast8_t errorState();
|
||||
inline bool isFilamentChange()
|
||||
{
|
||||
return flags & TEMPERATURE_CONTROLLER_FLAG_JAM;
|
||||
return flags & TEMPERATURE_CONTROLLER_FLAG_FILAMENTCHANGE;
|
||||
}
|
||||
void setJammed(bool on);
|
||||
inline bool isJammed()
|
||||
{
|
||||
return flags & TEMPERATURE_CONTROLLER_FLAG_JAM;
|
||||
}
|
||||
inline bool isSlowedDown()
|
||||
{
|
||||
return flags & TEMPERATURE_CONTROLLER_FLAG_SLOWDOWN;
|
||||
return flags & TEMPERATURE_CONTROLLER_FLAG_SLOWDOWN;
|
||||
}
|
||||
#if EXTRUDER_JAM_CONTROL
|
||||
inline void setFilamentChange(bool on)
|
||||
{
|
||||
flags &= ~TEMPERATURE_CONTROLLER_FLAG_FILAMENTCHANGE;
|
||||
if(on) flags |= TEMPERATURE_CONTROLLER_FLAG_FILAMENTCHANGE;
|
||||
}
|
||||
void setJammed(bool on);
|
||||
inline void setSlowedDown(bool on)
|
||||
{
|
||||
flags &= ~TEMPERATURE_CONTROLLER_FLAG_SLOWDOWN;
|
||||
|
@ -157,18 +172,47 @@ class Extruder;
|
|||
extern Extruder extruder[];
|
||||
|
||||
#if EXTRUDER_JAM_CONTROL
|
||||
#if JAM_METHOD == 1
|
||||
#define _TEST_EXTRUDER_JAM(x,pin) {\
|
||||
uint8_t sig = READ(pin);extruder[x].jamStepsSinceLastSignal += extruder[x].jamLastDir;\
|
||||
if(extruder[x].jamLastSignal != sig && abs(extruder[x].jamStepsSinceLastSignal - extruder[x].jamLastChangeAt) > JAM_MIN_STEPS) {\
|
||||
if(sig) {extruder[x].resetJamSteps();} \
|
||||
extruder[x].jamLastSignal = sig;extruder[x].jamLastChangeAt = extruder[x].jamStepsSinceLastSignal;\
|
||||
} else if(abs(extruder[x].jamStepsSinceLastSignal) > JAM_ERROR_STEPS && !Printer::isDebugJamOrDisabled() && !extruder[x].tempControl.isJammed()) \
|
||||
extruder[x].tempControl.setJammed(true);\
|
||||
}
|
||||
uint8_t sig = READ(pin);extruder[x].jamStepsSinceLastSignal += extruder[x].jamLastDir;\
|
||||
if(extruder[x].jamLastSignal != sig && abs(extruder[x].jamStepsSinceLastSignal - extruder[x].jamLastChangeAt) > JAM_MIN_STEPS) {\
|
||||
if(sig) {extruder[x].resetJamSteps();} \
|
||||
extruder[x].jamLastSignal = sig;extruder[x].jamLastChangeAt = extruder[x].jamStepsSinceLastSignal;\
|
||||
} else if(abs(extruder[x].jamStepsSinceLastSignal) > extruder[x].jamErrorSteps && !Printer::isDebugJamOrDisabled() && !extruder[x].tempControl.isJammed() && !extruder[x].tempControl.isFilamentChange()) {\
|
||||
if(extruder[x].jamLastDir > 0) {\
|
||||
extruder[x].tempControl.setJammed(true);\
|
||||
} else {\
|
||||
extruder[x].tempControl.setFilamentChange(true);}} \
|
||||
}
|
||||
#define RESET_EXTRUDER_JAM(x,dir) extruder[x].jamLastDir = dir ? 1 : -1;
|
||||
#elif JAM_METHOD == 2
|
||||
#define _TEST_EXTRUDER_JAM(x,pin) {\
|
||||
uint8_t sig = READ(pin);\
|
||||
if(sig != extruder[x].jamLastSignal) {\
|
||||
extruder[x].jamLastSignal ) sig;\
|
||||
if(sig)\
|
||||
{extruder[x].tempControl.setFilamentChange(true);extruder[x].tempControl.setJammed(true);} \
|
||||
else if(!Printer::isDebugJamOrDisabled() && extruder[x].tempControl.isJammed()) \
|
||||
{extruder[x].resetJamSteps();}}\
|
||||
}
|
||||
#define RESET_EXTRUDER_JAM(x,dir)
|
||||
#elif JAM_METHOD == 3
|
||||
#define _TEST_EXTRUDER_JAM(x,pin) {\
|
||||
uint8_t sig = !READ(pin);\
|
||||
if(sig != extruder[x].jamLastSignal) {\
|
||||
extruder[x].jamLastSignal ) sig;\
|
||||
if(sig)\
|
||||
{extruder[x].tempControl.setFilamentChange(true);extruder[x].tempControl.setJammed(true);} \
|
||||
else if(!Printer::isDebugJamOrDisabled() && extruder[x].tempControl.isJammed()) \
|
||||
{extruder[x].resetJamSteps();}}\
|
||||
}
|
||||
#define RESET_EXTRUDER_JAM(x,dir)
|
||||
#else
|
||||
#error Unknown value for JAM_METHOD
|
||||
#endif
|
||||
#define ___TEST_EXTRUDER_JAM(x,y) _TEST_EXTRUDER_JAM(x,y)
|
||||
#define __TEST_EXTRUDER_JAM(x) ___TEST_EXTRUDER_JAM(x,EXT ## x ## _JAM_PIN)
|
||||
#define TEST_EXTRUDER_JAM(x) __TEST_EXTRUDER_JAM(x)
|
||||
#define RESET_EXTRUDER_JAM(x,dir) extruder[x].jamLastDir = dir ? 1 : -1;
|
||||
#else
|
||||
#define TEST_EXTRUDER_JAM(x)
|
||||
#define RESET_EXTRUDER_JAM(x,dir)
|
||||
|
@ -193,13 +237,15 @@ public:
|
|||
static int mixingS; ///< Sum of all weights
|
||||
static uint8_t mixingDir; ///< Direction flag
|
||||
static uint8_t activeMixingExtruder;
|
||||
static void recomputeMixingExtruderSteps();
|
||||
#endif
|
||||
uint8_t id;
|
||||
int32_t xOffset;
|
||||
int32_t yOffset;
|
||||
int32_t zOffset;
|
||||
float stepsPerMM; ///< Steps per mm.
|
||||
//Davinci Specific, as Pin is 128 int8 is not enough
|
||||
int16_t enablePin; ///< Pin to enable extruder stepper motor.
|
||||
uint8_t enablePin; ///< Pin to enable extruder stepper motor.
|
||||
// uint8_t directionPin; ///< Pin number to assign the direction.
|
||||
// uint8_t stepPin; ///< Pin number for a step.
|
||||
uint8_t enableOn;
|
||||
|
@ -208,18 +254,19 @@ public:
|
|||
float maxAcceleration; ///< Maximum acceleration in mm/s^2.
|
||||
float maxStartFeedrate; ///< Maximum start feedrate in mm/s.
|
||||
int32_t extrudePosition; ///< Current extruder position in steps.
|
||||
int16_t watchPeriod; ///< Time in seconds, a M109 command will wait to stabalize temperature
|
||||
int16_t waitRetractTemperature; ///< Temperature to retract the filament when waiting for heatup
|
||||
int16_t waitRetractUnits; ///< Units to retract the filament when waiting for heatup
|
||||
int16_t watchPeriod; ///< Time in seconds, a M109 command will wait to stabilize temperature
|
||||
int16_t waitRetractTemperature; ///< Temperature to retract the filament when waiting for heat up
|
||||
int16_t waitRetractUnits; ///< Units to retract the filament when waiting for heat up
|
||||
#if USE_ADVANCE
|
||||
#if ENABLE_QUADRATIC_ADVANCE
|
||||
float advanceK; ///< Koefficient for advance algorithm. 0 = off
|
||||
float advanceK; ///< Coefficient for advance algorithm. 0 = off
|
||||
#endif
|
||||
float advanceL;
|
||||
int16_t advanceBacklash;
|
||||
#endif // USE_ADVANCE
|
||||
#if MIXING_EXTRUDER > 0
|
||||
int mixingW; ///< Weight for this extruder when mixing steps
|
||||
int mixingWB; ///< Weight after balancing extruder steps per mm
|
||||
int mixingE; ///< Cumulated error for this step.
|
||||
int virtualWeights[VIRTUAL_EXTRUDER]; // Virtual extruder weights
|
||||
#endif // MIXING_EXTRUDER > 0
|
||||
|
@ -231,11 +278,14 @@ public:
|
|||
float diameter;
|
||||
uint8_t flags;
|
||||
#if EXTRUDER_JAM_CONTROL
|
||||
int16_t jamStepsSinceLastSignal; // when was the last signal
|
||||
int32_t jamStepsSinceLastSignal; // when was the last signal
|
||||
uint8_t jamLastSignal; // what was the last signal
|
||||
int8_t jamLastDir;
|
||||
int16_t jamStepsOnSignal;
|
||||
int16_t jamLastChangeAt;
|
||||
int32_t jamStepsOnSignal;
|
||||
int32_t jamLastChangeAt;
|
||||
int32_t jamSlowdownSteps;
|
||||
int32_t jamErrorSteps;
|
||||
uint8_t jamSlowdownTo;
|
||||
#endif
|
||||
|
||||
// Methods here
|
||||
|
@ -280,22 +330,32 @@ public:
|
|||
//Davinci Specific, allow to cool down but not heat for a period
|
||||
static millis_t disableheat_time;
|
||||
static float getHeatedBedTemperature();
|
||||
static void setTemperatureForExtruder(float temp_celsius,uint8_t extr,bool beep = false);
|
||||
static void setTemperatureForExtruder(float temp_celsius,uint8_t extr,bool beep = false,bool wait = false);
|
||||
static void pauseExtruders();
|
||||
static void unpauseExtruders();
|
||||
};
|
||||
|
||||
#if HAVE_HEATED_BED
|
||||
#define NUM_TEMPERATURE_LOOPS NUM_EXTRUDER+1
|
||||
#define HEATED_BED_INDEX NUM_EXTRUDER
|
||||
extern TemperatureController heatedBedController;
|
||||
#else
|
||||
#define NUM_TEMPERATURE_LOOPS NUM_EXTRUDER
|
||||
#define HEATED_BED_INDEX NUM_EXTRUDER-1
|
||||
#endif
|
||||
#if FAN_THERMO_PIN > -1
|
||||
#define THERMO_CONTROLLER_INDEX HEATED_BED_INDEX+1
|
||||
extern TemperatureController thermoController;
|
||||
#else
|
||||
#define THERMO_CONTROLLER_INDEX HEATED_BED_INDEX
|
||||
#endif
|
||||
#define NUM_TEMPERATURE_LOOPS THERMO_CONTROLLER_INDEX+1
|
||||
|
||||
#define TEMP_INT_TO_FLOAT(temp) ((float)(temp)/(float)(1<<CELSIUS_EXTRA_BITS))
|
||||
#define TEMP_FLOAT_TO_INT(temp) ((int)((temp)*(1<<CELSIUS_EXTRA_BITS)))
|
||||
|
||||
//extern Extruder *Extruder::current;
|
||||
#if NUM_TEMPERATURE_LOOPS > 0
|
||||
extern TemperatureController *tempController[NUM_TEMPERATURE_LOOPS];
|
||||
#endif
|
||||
extern uint8_t autotuneIndex;
|
||||
|
||||
|
||||
|
|
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
|
@ -22,26 +22,33 @@
|
|||
#ifndef _REPETIER_H
|
||||
#define _REPETIER_H
|
||||
|
||||
#define REPETIER_VERSION "0.92"
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
#define REPETIER_VERSION "0.92.10"
|
||||
|
||||
// ##########################################################################################
|
||||
// ## Debug configuration ##
|
||||
// ##########################################################################################
|
||||
// These are run time sqitchable debug flags
|
||||
// These are run time switchable debug flags
|
||||
enum debugFlags {DEB_ECHO = 0x1, DEB_INFO = 0x2, DEB_ERROR = 0x4,DEB_DRYRUN = 0x8,
|
||||
DEB_COMMUNICATION = 0x10, DEB_NOMOVES = 0x20, DEB_DEBUG = 0x40};
|
||||
DEB_COMMUNICATION = 0x10, DEB_NOMOVES = 0x20, DEB_DEBUG = 0x40
|
||||
};
|
||||
|
||||
/** Uncomment, to see detailed data for every move. Only for debugging purposes! */
|
||||
//#define DEBUG_QUEUE_MOVE
|
||||
/** write infos about path planner changes */
|
||||
//#define DEBUG_PLANNER
|
||||
/** Allows M111 to set bit 5 (16) which disables all commands except M111. This can be used
|
||||
to test your data througput or search for communication problems. */
|
||||
to test your data throughput or search for communication problems. */
|
||||
#define INCLUDE_DEBUG_COMMUNICATION 1
|
||||
// Echo all ascii commands after receiving
|
||||
//#define DEBUG_ECHO_ASCII
|
||||
/** Allows M111 so set bit 6 (32) which disables moves, at the first tried step. In combination
|
||||
with a dry run, you can test the speed of path computations, which are still performed. */
|
||||
#define INCLUDE_DEBUG_NO_MOVE 1
|
||||
/** Writes the free RAM to output, if it is less then at the last test. Should always return
|
||||
values >500 for safety, since it doesn't catch every function call. Nice to tweak cache
|
||||
usage or for seraching for memory induced errors. Switch it off for production, it costs execution time. */
|
||||
usage or for searching for memory induced errors. Switch it off for production, it costs execution time. */
|
||||
//#define DEBUG_FREE_MEMORY
|
||||
//#define DEBUG_ADVANCE
|
||||
/** If enabled, writes the created generic table to serial port at startup. */
|
||||
|
@ -49,8 +56,8 @@ usage or for seraching for memory induced errors. Switch it off for production,
|
|||
/** If enabled, steps to move and moved steps are compared. */
|
||||
//#define DEBUG_STEPCOUNT
|
||||
/** This enables code to make M666 drop an ok, so you get problems with communication. It is to test host robustness. */
|
||||
#define DEBUG_COM_ERRORS
|
||||
/** Adds a menu point in quick settings to write debg informations to the host in case of hangs where the ui still works. */
|
||||
//#define DEBUG_COM_ERRORS
|
||||
/** Adds a menu point in quick settings to write debug informations to the host in case of hangs where the ui still works. */
|
||||
//#define DEBUG_PRINT
|
||||
//#define DEBUG_DELTA_OVERFLOW
|
||||
//#define DEBUG_DELTA_REALPOS
|
||||
|
@ -60,6 +67,8 @@ usage or for seraching for memory induced errors. Switch it off for production,
|
|||
//#define DEBUG_SEGMENT_LENGTH
|
||||
// Find the maximum real jerk during a print
|
||||
//#define DEBUG_REAL_JERK
|
||||
// Debug reason for not mounting a sd card
|
||||
//#define DEBUG_SD_ERROR
|
||||
// Uncomment the following line to enable debugging. You can better control debugging below the following line
|
||||
//#define DEBUG
|
||||
|
||||
|
@ -71,8 +80,10 @@ usage or for seraching for memory induced errors. Switch it off for production,
|
|||
#define BIPOD 5
|
||||
#define XZ_GANTRY 8
|
||||
#define ZX_GANTRY 9
|
||||
#define GANTRY_FAKE 10
|
||||
|
||||
#define WIZARD_STACK_SIZE 8
|
||||
#define IGNORE_COORDINATE 999999
|
||||
|
||||
// Uncomment if no analyzer is connected
|
||||
//#define ANALYZER
|
||||
|
@ -117,19 +128,14 @@ usage or for seraching for memory induced errors. Switch it off for production,
|
|||
#define ANALOG_REF_INT_2_56 _BV(REFS0) | _BV(REFS1)
|
||||
#define ANALOG_REF ANALOG_REF_AVCC
|
||||
|
||||
// MS1 MS2 Stepper Driver Microstepping mode table
|
||||
#define MICROSTEP1 LOW,LOW
|
||||
#define MICROSTEP2 HIGH,LOW
|
||||
#define MICROSTEP4 LOW,HIGH
|
||||
#define MICROSTEP8 HIGH,HIGH
|
||||
#define MICROSTEP16 HIGH,HIGH
|
||||
|
||||
#define HOME_ORDER_XYZ 1
|
||||
#define HOME_ORDER_XZY 2
|
||||
#define HOME_ORDER_YXZ 3
|
||||
#define HOME_ORDER_YZX 4
|
||||
#define HOME_ORDER_ZXY 5
|
||||
#define HOME_ORDER_ZYX 6
|
||||
#define HOME_ORDER_ZXYTZ 7 // Needs hot hotend for correct homing
|
||||
#define HOME_ORDER_XYTZ 8 // Needs hot hotend for correct homing
|
||||
|
||||
#define NO_CONTROLLER 0
|
||||
#define UICONFIG_CONTROLLER 1
|
||||
|
@ -150,6 +156,13 @@ usage or for seraching for memory induced errors. Switch it off for production,
|
|||
#define CONTROLLER_GAMEDUINO2 16
|
||||
#define CONTROLLER_MIREGLI 17
|
||||
#define CONTROLLER_GATE_3NOVATICA 18
|
||||
#define CONTROLLER_SPARKLCD 19
|
||||
#define CONTROLLER_BAM_DICE_DUE 20
|
||||
#define CONTROLLER_VIKI2 21
|
||||
#define CONTROLLER_LCD_MP_PHARAOH_DUE 22
|
||||
#define CONTROLLER_SPARKLCD_ADAPTER 23
|
||||
#define CONTROLLER_ZONESTAR 24
|
||||
#define CONTROLLER_FELIX_DUE 405
|
||||
|
||||
//direction flags
|
||||
#define X_DIRPOS 1
|
||||
|
@ -174,9 +187,128 @@ usage or for seraching for memory induced errors. Switch it off for production,
|
|||
// add pid control
|
||||
#define TEMP_PID 1
|
||||
|
||||
#define PRINTER_MODE_FFF 0
|
||||
#define PRINTER_MODE_LASER 1
|
||||
#define PRINTER_MODE_CNC 2
|
||||
|
||||
#define ILLEGAL_Z_PROBE -888
|
||||
|
||||
// we can not prevent this as some configurations need a parameter and others not
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
|
||||
#include "Configuration.h"
|
||||
|
||||
#ifndef SHARED_EXTRUDER_HEATER
|
||||
#define SHARED_EXTRUDER_HEATER 0
|
||||
#endif
|
||||
|
||||
#ifndef DUAL_X_AXIS
|
||||
#define DUAL_X_AXIS 0
|
||||
#endif
|
||||
|
||||
#ifndef LAZY_DUAL_X_AXIS
|
||||
#define LAZY_DUAL_X_AXIS 0
|
||||
#endif
|
||||
|
||||
#ifndef MOVE_X_WHEN_HOMED
|
||||
#define MOVE_X_WHEN_HOMED 0
|
||||
#endif
|
||||
#ifndef MOVE_Y_WHEN_HOMED
|
||||
#define MOVE_Y_WHEN_HOMED 0
|
||||
#endif
|
||||
#ifndef MOVE_Z_WHEN_HOMED
|
||||
#define MOVE_Z_WHEN_HOMED 0
|
||||
#endif
|
||||
|
||||
#if SHARED_EXTRUDER_HEATER || MIXING_EXTRUDER
|
||||
#undef EXT1_HEATER_PIN
|
||||
#undef EXT2_HEATER_PIN
|
||||
#undef EXT3_HEATER_PIN
|
||||
#undef EXT4_HEATER_PIN
|
||||
#undef EXT5_HEATER_PIN
|
||||
#define EXT1_HEATER_PIN -1
|
||||
#define EXT2_HEATER_PIN -1
|
||||
#define EXT3_HEATER_PIN -1
|
||||
#define EXT4_HEATER_PIN -1
|
||||
#define EXT5_HEATER_PIN -1
|
||||
#endif
|
||||
|
||||
#ifndef BOARD_FAN_SPEED
|
||||
#define BOARD_FAN_SPEED
|
||||
#endif
|
||||
|
||||
#ifndef MAX_JERK_DISTANCE
|
||||
#define MAX_JERK_DISTANCE 0.6
|
||||
#endif
|
||||
#define XY_GANTRY 1
|
||||
#define YX_GANTRY 2
|
||||
#define DELTA 3
|
||||
#define TUGA 4
|
||||
#define BIPOD 5
|
||||
#define XZ_GANTRY 8
|
||||
#define ZX_GANTRY 9
|
||||
#if defined(FAST_COREXYZ) && !(DRIVE_SYSTEM==XY_GANTRY || DRIVE_SYSTEM==YX_GANTRY || DRIVE_SYSTEM==XZ_GANTRY || DRIVE_SYSTEM==ZX_GANTRY || DRIVE_SYSTEM==GANTRY_FAKE)
|
||||
#undef FAST_COREXYZ
|
||||
#endif
|
||||
#ifdef FAST_COREXYZ
|
||||
#if DELTA_SEGMENTS_PER_SECOND_PRINT < 30
|
||||
#undef DELTA_SEGMENTS_PER_SECOND_PRINT
|
||||
#define DELTA_SEGMENTS_PER_SECOND_PRINT 30 // core is linear, no subsegments needed
|
||||
#endif
|
||||
#if DELTA_SEGMENTS_PER_SECOND_MOVE < 30
|
||||
#undef DELTA_SEGMENTS_PER_SECOND_MOVE
|
||||
#define DELTA_SEGMENTS_PER_SECOND_MOVE 30
|
||||
#endif
|
||||
#endif
|
||||
|
||||
inline void memcopy2(void *dest,void *source) {
|
||||
*((int16_t*)dest) = *((int16_t*)source);
|
||||
}
|
||||
inline void memcopy4(void *dest,void *source) {
|
||||
*((int32_t*)dest) = *((int32_t*)source);
|
||||
}
|
||||
|
||||
#ifndef JSON_OUTPUT
|
||||
#define JSON_OUTPUT 0
|
||||
#endif
|
||||
|
||||
#if !defined(ZPROBE_MIN_TEMPERATURE) && defined(ZHOME_MIN_TEMPERATURE)
|
||||
#define ZPROBE_MIN_TEMPERATURE ZHOME_MIN_TEMPERATURE
|
||||
#endif
|
||||
|
||||
#if FEATURE_Z_PROBE && Z_PROBE_PIN < 0
|
||||
#error You need to define Z_PROBE_PIN to use z probe!
|
||||
#endif
|
||||
|
||||
#if DISTORTION_CORRECTION
|
||||
#if !FEATURE_Z_PROBE
|
||||
#error Distortion correction requires the z probe feature to be enabled and configured!
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef MAX_ROOM_TEMPERATURE
|
||||
#define MAX_ROOM_TEMPERATURE 40
|
||||
#endif
|
||||
#ifndef ZHOME_X_POS
|
||||
#define ZHOME_X_POS IGNORE_COORDINATE
|
||||
#endif
|
||||
#ifndef ZHOME_Y_POS
|
||||
#define ZHOME_Y_POS IGNORE_COORDINATE
|
||||
#endif
|
||||
|
||||
// MS1 MS2 Stepper Driver Micro stepping mode table
|
||||
#define MICROSTEP1 LOW,LOW
|
||||
#define MICROSTEP2 HIGH,LOW
|
||||
#define MICROSTEP4 LOW,HIGH
|
||||
#define MICROSTEP8 HIGH,HIGH
|
||||
#if (MOTHERBOARD == 501)
|
||||
#define MICROSTEP16 LOW,LOW
|
||||
#else
|
||||
#define MICROSTEP16 HIGH,HIGH
|
||||
#endif
|
||||
#define MICROSTEP32 HIGH,HIGH
|
||||
|
||||
#define GCODE_BUFFER_SIZE 1
|
||||
|
||||
#ifndef FEATURE_BABYSTEPPING
|
||||
|
@ -189,20 +321,34 @@ usage or for seraching for memory induced errors. Switch it off for production,
|
|||
#define Z_PROBE_REPETITIONS 1
|
||||
#endif
|
||||
|
||||
#define SPEED_MIN_MILLIS 300
|
||||
#define SPEED_MAX_MILLIS 50
|
||||
#ifndef MINMAX_HARDWARE_ENDSTOP_Z2
|
||||
#define MINMAX_HARDWARE_ENDSTOP_Z2 0
|
||||
#define Z2_MINMAX_PIN -1
|
||||
#endif
|
||||
|
||||
#if MINMAX_HARDWARE_ENDSTOP_Z2 && Z2_MINMAX_PIN > -1
|
||||
#define MULTI_ZENDSTOP_HOMING 1
|
||||
#define MULTI_ZENDSTOP_ALL 3
|
||||
#else
|
||||
#define MULTI_ZENDSTOP_HOMING 0
|
||||
#endif
|
||||
|
||||
#define SPEED_MIN_MILLIS 400
|
||||
#define SPEED_MAX_MILLIS 60
|
||||
#define SPEED_MAGNIFICATION 100.0f
|
||||
|
||||
#define SOFTWARE_LEVELING (FEATURE_SOFTWARE_LEVELING && (DRIVE_SYSTEM==DELTA))
|
||||
#define SOFTWARE_LEVELING (defined(FEATURE_SOFTWARE_LEVELING) && (DRIVE_SYSTEM==DELTA))
|
||||
/** \brief Horizontal distance bridged by the diagonal push rod when the end effector is in the center. It is pretty close to 50% of the push rod length (250 mm).
|
||||
*/
|
||||
#if !defined(ROD_RADIUS) && DRIVE_SYSTEM == DELTA
|
||||
#define ROD_RADIUS (PRINTER_RADIUS-END_EFFECTOR_HORIZONTAL_OFFSET-CARRIAGE_HORIZONTAL_OFFSET)
|
||||
#endif
|
||||
|
||||
#ifndef UI_SPEEDDEPENDENT_POSITIONING
|
||||
#define UI_SPEEDDEPENDENT_POSITIONING true
|
||||
#endif
|
||||
|
||||
#if DRIVE_SYSTEM==DELTA || DRIVE_SYSTEM==TUGA || DRIVE_SYSTEM==BIPOD
|
||||
#if DRIVE_SYSTEM==DELTA || DRIVE_SYSTEM==TUGA || DRIVE_SYSTEM==BIPOD || defined(FAST_COREXYZ)
|
||||
#define NONLINEAR_SYSTEM 1
|
||||
#else
|
||||
#define NONLINEAR_SYSTEM 0
|
||||
|
@ -212,16 +358,16 @@ usage or for seraching for memory induced errors. Switch it off for production,
|
|||
#define MANUAL_CONTROL 1
|
||||
#endif
|
||||
|
||||
#define GANTRY ( DRIVE_SYSTEM==XY_GANTRY || DRIVE_SYSTEM==YX_GANTRY || DRIVE_SYSTEM==XZ_GANTRY || DRIVE_SYSTEM==ZX_GANTRY)
|
||||
#define GANTRY ( DRIVE_SYSTEM==XY_GANTRY || DRIVE_SYSTEM==YX_GANTRY || DRIVE_SYSTEM==XZ_GANTRY || DRIVE_SYSTEM==ZX_GANTRY || DRIVE_SYSTEM==GANTRY_FAKE)
|
||||
|
||||
//Step to split a cirrcle in small Lines
|
||||
//Step to split a circle in small Lines
|
||||
#ifndef MM_PER_ARC_SEGMENT
|
||||
#define MM_PER_ARC_SEGMENT 1
|
||||
#define MM_PER_ARC_SEGMENT_BIG 3
|
||||
#else
|
||||
#define MM_PER_ARC_SEGMENT_BIG MM_PER_ARC_SEGMENT
|
||||
#endif
|
||||
//After this count of steps a new SIN / COS caluclation is startet to correct the circle interpolation
|
||||
//After this count of steps a new SIN / COS calculation is started to correct the circle interpolation
|
||||
#define N_ARC_CORRECTION 25
|
||||
|
||||
// Test for shared cooler
|
||||
|
@ -239,16 +385,28 @@ usage or for seraching for memory induced errors. Switch it off for production,
|
|||
#define SHARED_COOLER 0
|
||||
#endif
|
||||
|
||||
#ifndef START_STEP_WITH_HIGH
|
||||
#define START_STEP_WITH_HIGH 1
|
||||
#endif
|
||||
|
||||
#if NUM_EXTRUDER > 0 && EXT0_TEMPSENSOR_TYPE == 101
|
||||
#define SUPPORT_MAX6675
|
||||
#endif
|
||||
|
||||
#if NUM_EXTRUDER > 0 && EXT0_TEMPSENSOR_TYPE == 102
|
||||
#define SUPPORT_MAX31855
|
||||
#endif
|
||||
|
||||
// Test for shared coolers between extruders and mainboard
|
||||
#if EXT0_EXTRUDER_COOLER_PIN > -1 && EXT0_EXTRUDER_COOLER_PIN == FAN_BOARD_PIN
|
||||
#define SHARED_COOLER_BOARD_EXT 1
|
||||
#define SHARED_COOLER_BOARD_EXT 1
|
||||
#else
|
||||
#define SHARED_COOLER_BOARD_EXT 0
|
||||
#define SHARED_COOLER_BOARD_EXT 0
|
||||
#endif
|
||||
|
||||
#if defined(UI_SERVO_CONTROL) && UI_SERVO_CONTROL > FEATURE_SERVO
|
||||
#undef UI_SERVO_CONTROL
|
||||
#define UI_SERVO_CONTROL FEATURE_SERVO
|
||||
#undef UI_SERVO_CONTROL
|
||||
#define UI_SERVO_CONTROL FEATURE_SERVO
|
||||
#endif
|
||||
|
||||
#if (defined(EXT0_JAM_PIN) && EXT0_JAM_PIN > -1) || (defined(EXT1_JAM_PIN) && EXT1_JAM_PIN > -1) || (defined(EXT2_JAM_PIN) && EXT2_JAM_PIN > -1) || (defined(EXT3_JAM_PIN) && EXT3_JAM_PIN > -1) || (defined(EXT4_JAM_PIN) && EXT4_JAM_PIN > -1) || (defined(EXT5_JAM_PIN) && EXT5_JAM_PIN > -1)
|
||||
|
@ -256,6 +414,9 @@ usage or for seraching for memory induced errors. Switch it off for production,
|
|||
#else
|
||||
#define EXTRUDER_JAM_CONTROL 0
|
||||
#endif
|
||||
#ifndef JAM_METHOD
|
||||
#define JAM_METHOD 1
|
||||
#endif
|
||||
|
||||
#if NUM_EXTRUDER > 0 && EXT0_TEMPSENSOR_TYPE < 101
|
||||
#define EXT0_ANALOG_INPUTS 1
|
||||
|
@ -269,7 +430,7 @@ usage or for seraching for memory induced errors. Switch it off for production,
|
|||
#define EXT0_ANALOG_CHANNEL
|
||||
#endif
|
||||
|
||||
#if NUM_EXTRUDER>1 && EXT1_TEMPSENSOR_TYPE<101
|
||||
#if NUM_EXTRUDER > 1 && EXT1_TEMPSENSOR_TYPE < 101
|
||||
#define EXT1_ANALOG_INPUTS 1
|
||||
#define EXT1_SENSOR_INDEX EXT0_ANALOG_INPUTS
|
||||
#define EXT1_ANALOG_CHANNEL ACCOMMA0 EXT1_TEMPSENSOR_PIN
|
||||
|
@ -281,7 +442,7 @@ usage or for seraching for memory induced errors. Switch it off for production,
|
|||
#define EXT1_ANALOG_CHANNEL
|
||||
#endif
|
||||
|
||||
#if NUM_EXTRUDER>2 && EXT2_TEMPSENSOR_TYPE<101
|
||||
#if NUM_EXTRUDER > 2 && EXT2_TEMPSENSOR_TYPE < 101
|
||||
#define EXT2_ANALOG_INPUTS 1
|
||||
#define EXT2_SENSOR_INDEX EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS
|
||||
#define EXT2_ANALOG_CHANNEL ACCOMMA1 EXT2_TEMPSENSOR_PIN
|
||||
|
@ -317,7 +478,7 @@ usage or for seraching for memory induced errors. Switch it off for production,
|
|||
#define EXT4_ANALOG_CHANNEL
|
||||
#endif
|
||||
|
||||
#if NUM_EXTRUDER>5 && EXT5_TEMPSENSOR_TYPE<101
|
||||
#if NUM_EXTRUDER > 5 && EXT5_TEMPSENSOR_TYPE < 101
|
||||
#define EXT5_ANALOG_INPUTS 1
|
||||
#define EXT5_SENSOR_INDEX EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS+EXT2_ANALOG_INPUTS+EXT3_ANALOG_INPUTS+EXT4_ANALOG_INPUTS
|
||||
#define EXT5_ANALOG_CHANNEL ACCOMMA4 EXT5_TEMPSENSOR_PIN
|
||||
|
@ -329,16 +490,36 @@ usage or for seraching for memory induced errors. Switch it off for production,
|
|||
#define EXT5_ANALOG_CHANNEL
|
||||
#endif
|
||||
|
||||
#if HAVE_HEATED_BED && HEATED_BED_SENSOR_TYPE<101
|
||||
#if HAVE_HEATED_BED && HEATED_BED_SENSOR_TYPE < 101
|
||||
#define BED_ANALOG_INPUTS 1
|
||||
#define BED_SENSOR_INDEX EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS+EXT2_ANALOG_INPUTS+EXT3_ANALOG_INPUTS+EXT4_ANALOG_INPUTS+EXT5_ANALOG_INPUTS
|
||||
#define BED_ANALOG_CHANNEL ACCOMMA5 HEATED_BED_SENSOR_PIN
|
||||
#undef KOMMA
|
||||
#define KOMMA ,
|
||||
#define BED_KOMMA ,
|
||||
#else
|
||||
#define BED_ANALOG_INPUTS 0
|
||||
#define BED_SENSOR_INDEX HEATED_BED_SENSOR_PIN
|
||||
#define BED_ANALOG_CHANNEL
|
||||
#define BED_KOMMA ACCOMMA5
|
||||
#endif
|
||||
|
||||
#if FAN_THERMO_THERMISTOR_PIN > -1 && FAN_THERMO_PIN > -1
|
||||
#define THERMO_ANALOG_INPUTS 1
|
||||
#define THERMO_ANALOG_INDEX EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS+EXT2_ANALOG_INPUTS+EXT3_ANALOG_INPUTS+EXT4_ANALOG_INPUTS+EXT5_ANALOG_INPUTS+BED_ANALOG_INPUTS
|
||||
#define THERMO_ANALOG_CHANNEL BED_KOMMA FAN_THERMO_THERMISTOR_PIN
|
||||
#define THERMO_COMMA ,
|
||||
#else
|
||||
#define THERMO_ANALOG_INPUTS 0
|
||||
#define THERMO_ANALOG_CHANNEL
|
||||
#define THERMO_COMMA BED_KOMMA
|
||||
#endif
|
||||
|
||||
#if defined(ADC_KEYPAD_PIN) && (ADC_KEYPAD_PIN > -1)
|
||||
#define KEYPAD_ANALOG_INPUTS 1
|
||||
#define KEYPAD_ANALOG_INDEX EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS+EXT2_ANALOG_INPUTS+EXT3_ANALOG_INPUTS+EXT4_ANALOG_INPUTS+EXT5_ANALOG_INPUTS+BED_ANALOG_INPUTS+THERMO_ANALOG_INPUTS
|
||||
#define KEYPAD_ANALOG_CHANNEL THERMO_COMMA ADC_KEYPAD_PIN
|
||||
#else
|
||||
#define KEYPAD_ANALOG_INPUTS 0
|
||||
#define KEYPAD_ANALOG_CHANNEL
|
||||
#endif
|
||||
|
||||
#ifndef DEBUG_FREE_MEMORY
|
||||
|
@ -348,10 +529,10 @@ usage or for seraching for memory induced errors. Switch it off for production,
|
|||
#endif
|
||||
|
||||
/** \brief number of analog input signals. Normally 1 for each temperature sensor */
|
||||
#define ANALOG_INPUTS (EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS+EXT2_ANALOG_INPUTS+EXT3_ANALOG_INPUTS+EXT4_ANALOG_INPUTS+EXT5_ANALOG_INPUTS+BED_ANALOG_INPUTS)
|
||||
#if ANALOG_INPUTS>0
|
||||
#define ANALOG_INPUTS (EXT0_ANALOG_INPUTS+EXT1_ANALOG_INPUTS+EXT2_ANALOG_INPUTS+EXT3_ANALOG_INPUTS+EXT4_ANALOG_INPUTS+EXT5_ANALOG_INPUTS+BED_ANALOG_INPUTS+THERMO_ANALOG_INPUTS+KEYPAD_ANALOG_INPUTS)
|
||||
#if ANALOG_INPUTS > 0
|
||||
/** Channels are the MUX-part of ADMUX register */
|
||||
#define ANALOG_INPUT_CHANNELS {EXT0_ANALOG_CHANNEL EXT1_ANALOG_CHANNEL EXT2_ANALOG_CHANNEL EXT3_ANALOG_CHANNEL EXT4_ANALOG_CHANNEL EXT5_ANALOG_CHANNEL BED_ANALOG_CHANNEL}
|
||||
#define ANALOG_INPUT_CHANNELS {EXT0_ANALOG_CHANNEL EXT1_ANALOG_CHANNEL EXT2_ANALOG_CHANNEL EXT3_ANALOG_CHANNEL EXT4_ANALOG_CHANNEL EXT5_ANALOG_CHANNEL BED_ANALOG_CHANNEL THERMO_ANALOG_CHANNEL KEYPAD_ANALOG_CHANNEL}
|
||||
#endif
|
||||
|
||||
#define MENU_MODE_SD_MOUNTED 1
|
||||
|
@ -361,6 +542,27 @@ usage or for seraching for memory induced errors. Switch it off for production,
|
|||
#define MENU_MODE_PRINTING 16
|
||||
#define MENU_MODE_FULL_PID 32
|
||||
#define MENU_MODE_DEADTIME 64
|
||||
|
||||
#ifndef BENDING_CORRECTION_A
|
||||
#define BENDING_CORRECTION_A 0
|
||||
#endif
|
||||
|
||||
#ifndef BENDING_CORRECTION_B
|
||||
#define BENDING_CORRECTION_B 0
|
||||
#endif
|
||||
|
||||
#ifndef BENDING_CORRECTION_C
|
||||
#define BENDING_CORRECTION_C 0
|
||||
#endif
|
||||
|
||||
#ifndef ACCELERATION_FACTOR_TOP
|
||||
#define ACCELERATION_FACTOR_TOP 100
|
||||
#endif
|
||||
|
||||
#ifndef KEEP_ALIVE_INTERVAL
|
||||
#define KEEP_ALIVE_INTERVAL 2000
|
||||
#endif
|
||||
|
||||
//Davinci Specific
|
||||
#define MENU_MODE_STOP_REQUESTED 1
|
||||
#define MENU_MODE_STOP_DONE 2
|
||||
|
@ -379,9 +581,9 @@ usage or for seraching for memory induced errors. Switch it off for production,
|
|||
|
||||
|
||||
#if UI_DISPLAY_TYPE != DISPLAY_U8G
|
||||
#if (defined(USER_KEY1_PIN) && (USER_KEY1_PIN==UI_DISPLAY_D5_PIN || USER_KEY1_PIN==UI_DISPLAY_D6_PIN || USER_KEY1_PIN==UI_DISPLAY_D7_PIN)) || (defined(USER_KEY2_PIN) && (USER_KEY2_PIN==UI_DISPLAY_D5_PIN || USER_KEY2_PIN==UI_DISPLAY_D6_PIN || USER_KEY2_PIN==UI_DISPLAY_D7_PIN)) || (defined(USER_KEY3_PIN) && (USER_KEY3_PIN==UI_DISPLAY_D5_PIN || USER_KEY3_PIN==UI_DISPLAY_D6_PIN || USER_KEY3_PIN==UI_DISPLAY_D7_PIN)) || (defined(USER_KEY4_PIN) && (USER_KEY4_PIN==UI_DISPLAY_D5_PIN || USER_KEY4_PIN==UI_DISPLAY_D6_PIN || USER_KEY4_PIN==UI_DISPLAY_D7_PIN))
|
||||
#error "You cannot use DISPLAY_D5_PIN, DISPLAY_D6_PIN or DISPLAY_D7_PIN for "User Keys" with character LCD display"
|
||||
#endif
|
||||
#if (defined(USER_KEY1_PIN) && (USER_KEY1_PIN==UI_DISPLAY_D5_PIN || USER_KEY1_PIN==UI_DISPLAY_D6_PIN || USER_KEY1_PIN==UI_DISPLAY_D7_PIN)) || (defined(USER_KEY2_PIN) && (USER_KEY2_PIN==UI_DISPLAY_D5_PIN || USER_KEY2_PIN==UI_DISPLAY_D6_PIN || USER_KEY2_PIN==UI_DISPLAY_D7_PIN)) || (defined(USER_KEY3_PIN) && (USER_KEY3_PIN==UI_DISPLAY_D5_PIN || USER_KEY3_PIN==UI_DISPLAY_D6_PIN || USER_KEY3_PIN==UI_DISPLAY_D7_PIN)) || (defined(USER_KEY4_PIN) && (USER_KEY4_PIN==UI_DISPLAY_D5_PIN || USER_KEY4_PIN==UI_DISPLAY_D6_PIN || USER_KEY4_PIN==UI_DISPLAY_D7_PIN))
|
||||
#error You cannot use DISPLAY_D5_PIN, DISPLAY_D6_PIN or DISPLAY_D7_PIN for "User Keys" with character LCD display
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -395,7 +597,7 @@ usage or for seraching for memory induced errors. Switch it off for production,
|
|||
#include "SdFat.h"
|
||||
#endif
|
||||
|
||||
#if ENABLE_BACKLASH_COMPENSATION && DRIVE_SYSTEM!=CARTESIAN
|
||||
#if ENABLE_BACKLASH_COMPENSATION && DRIVE_SYSTEM != CARTESIAN
|
||||
#undef ENABLE_BACKLASH_COMPENSATION
|
||||
#define ENABLE_BACKLASH_COMPENSATION false
|
||||
#endif
|
||||
|
@ -406,70 +608,275 @@ usage or for seraching for memory induced errors. Switch it off for production,
|
|||
#define uint32 uint32_t
|
||||
#define int32 int32_t
|
||||
|
||||
#define IGNORE_COORDINATE 999999
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
class RMath {
|
||||
class RMath
|
||||
{
|
||||
public:
|
||||
static inline float min(float a,float b) {
|
||||
if(a<b) return a;
|
||||
static inline float min(float a,float b)
|
||||
{
|
||||
if(a < b) return a;
|
||||
return b;
|
||||
}
|
||||
static inline float max(float a,float b) {
|
||||
if(a<b) return b;
|
||||
static inline float max(float a,float b)
|
||||
{
|
||||
if(a < b) return b;
|
||||
return a;
|
||||
}
|
||||
static inline int32_t min(int32_t a,int32_t b) {
|
||||
if(a<b) return a;
|
||||
static inline int32_t min(int32_t a,int32_t b)
|
||||
{
|
||||
if(a < b) return a;
|
||||
return b;
|
||||
}
|
||||
static inline int32_t min(int32_t a,int32_t b, int32_t c) {
|
||||
if(a<b) return a<c ? a : c;
|
||||
return b<c ? b : c;
|
||||
static inline int32_t min(int32_t a,int32_t b, int32_t c)
|
||||
{
|
||||
if(a < b) return a < c ? a : c;
|
||||
return b<c ? b : c;
|
||||
}
|
||||
static inline float min(float a,float b, float c) {
|
||||
if(a<b) return a<c ? a : c;
|
||||
return b<c ? b : c;
|
||||
static inline float min(float a,float b, float c)
|
||||
{
|
||||
if(a < b) return a < c ? a : c;
|
||||
return b < c ? b : c;
|
||||
}
|
||||
static inline int32_t max(int32_t a,int32_t b) {
|
||||
if(a<b) return b;
|
||||
static inline int32_t max(int32_t a,int32_t b)
|
||||
{
|
||||
if(a < b) return b;
|
||||
return a;
|
||||
}
|
||||
static inline int min(int a,int b) {
|
||||
if(a<b) return a;
|
||||
static inline int min(int a,int b)
|
||||
{
|
||||
if(a < b) return a;
|
||||
return b;
|
||||
}
|
||||
static inline uint16_t min(uint16_t a,uint16_t b) {
|
||||
if(a<b) return a;
|
||||
static inline uint16_t min(uint16_t a,uint16_t b)
|
||||
{
|
||||
if(a < b) return a;
|
||||
return b;
|
||||
}
|
||||
static inline int16_t max(int16_t a,int16_t b) {
|
||||
if(a<b) return b;
|
||||
static inline int16_t max(int16_t a,int16_t b)
|
||||
{
|
||||
if(a < b) return b;
|
||||
return a;
|
||||
}
|
||||
static inline uint16_t max(uint16_t a,uint16_t b) {
|
||||
if(a<b) return b;
|
||||
static inline uint16_t max(uint16_t a,uint16_t b)
|
||||
{
|
||||
if(a < b) return b;
|
||||
return a;
|
||||
}
|
||||
static inline unsigned long absLong(long a) {return a >= 0 ? a : -a;}
|
||||
static inline int32_t sqr(int32_t a) {return a*a;}
|
||||
static inline uint32_t sqr(uint32_t a) {return a*a;}
|
||||
static inline unsigned long absLong(long a)
|
||||
{
|
||||
return a >= 0 ? a : -a;
|
||||
}
|
||||
static inline int32_t sqr(int32_t a)
|
||||
{
|
||||
return a*a;
|
||||
}
|
||||
static inline uint32_t sqr(uint32_t a)
|
||||
{
|
||||
return a*a;
|
||||
}
|
||||
#ifdef SUPPORT_64_BIT_MATH
|
||||
static inline int64_t sqr(int64_t a) {return a*a;}
|
||||
static inline uint64_t sqr(uint64_t a) {return a*a;}
|
||||
static inline int64_t sqr(int64_t a)
|
||||
{
|
||||
return a*a;
|
||||
}
|
||||
static inline uint64_t sqr(uint64_t a)
|
||||
{
|
||||
return a*a;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline float sqr(float a) {return a*a;}
|
||||
static inline float sqr(float a)
|
||||
{
|
||||
return a*a;
|
||||
}
|
||||
};
|
||||
|
||||
class RVector3
|
||||
{
|
||||
public:
|
||||
float x, y, z;
|
||||
RVector3(float _x = 0,float _y = 0,float _z = 0):x(_x),y(_y),z(_z) {};
|
||||
RVector3(const RVector3 &a):x(a.x),y(a.y),z(a.z) {};
|
||||
|
||||
|
||||
/* const float &operator[](std::size_t idx) const
|
||||
{
|
||||
if(idx == 0) return x;
|
||||
if(idx == 1) return y;
|
||||
return z;
|
||||
};
|
||||
|
||||
float &operator[](std::size_t idx)
|
||||
{
|
||||
switch(idx) {
|
||||
case 0: return x;
|
||||
case 1: return y;
|
||||
case 2: return z;
|
||||
}
|
||||
return 0;
|
||||
};*/
|
||||
|
||||
inline bool operator==(const RVector3 &rhs)
|
||||
{
|
||||
return x==rhs.x && y==rhs.y && z==rhs.z;
|
||||
}
|
||||
inline bool operator!=(const RVector3 &rhs)
|
||||
{
|
||||
return !(*this==rhs);
|
||||
}
|
||||
inline RVector3& operator=(const RVector3 &rhs)
|
||||
{
|
||||
if(this!=&rhs)
|
||||
{
|
||||
x = rhs.x;
|
||||
y = rhs.y;
|
||||
z = rhs.z;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline RVector3& operator+=(const RVector3 &rhs)
|
||||
{
|
||||
x += rhs.x;
|
||||
y += rhs.y;
|
||||
z += rhs.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline RVector3& operator-=(const RVector3 &rhs)
|
||||
{
|
||||
x -= rhs.x;
|
||||
y -= rhs.y;
|
||||
z -= rhs.z;
|
||||
return *this;
|
||||
}
|
||||
inline RVector3 operator-() const
|
||||
{
|
||||
return RVector3(-x,-y,-z);
|
||||
}
|
||||
|
||||
inline float length() const
|
||||
{
|
||||
return sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
inline float lengthSquared() const
|
||||
{
|
||||
return (x*x+y*y+z*z);
|
||||
}
|
||||
|
||||
inline RVector3 cross(const RVector3 &b) const
|
||||
{
|
||||
return RVector3(y*b.z-z*b.y,z*b.x-x*b.z,x*b.y-y*b.x);
|
||||
}
|
||||
inline float scalar(const RVector3 &b) const
|
||||
{
|
||||
return (x*b.x+y*b.y+z*b.z);
|
||||
}
|
||||
inline RVector3 scale(float factor) const
|
||||
{
|
||||
return RVector3(x*factor,y*factor,z*factor);
|
||||
}
|
||||
inline void scaleIntern(float factor)
|
||||
{
|
||||
x*=factor;
|
||||
y*=factor;
|
||||
z*=factor;
|
||||
}
|
||||
inline void setMinimum(const RVector3 &b)
|
||||
{
|
||||
x = RMath::min(x,b.x);
|
||||
y = RMath::min(y,b.y);
|
||||
z = RMath::min(z,b.z);
|
||||
}
|
||||
inline void setMaximum(const RVector3 &b)
|
||||
{
|
||||
x = RMath::max(x,b.x);
|
||||
y = RMath::max(y,b.y);
|
||||
z = RMath::max(z,b.z);
|
||||
}
|
||||
inline float distance(const RVector3 &b) const
|
||||
{
|
||||
float dx = b.x-x,dy = b.y-y, dz = b.z-z;
|
||||
return (sqrt(dx*dx+dy*dy+dz*dz));
|
||||
}
|
||||
inline float angle(RVector3 &direction)
|
||||
{
|
||||
return static_cast<float>(acos(scalar(direction)/(length()*direction.length())));
|
||||
}
|
||||
|
||||
inline RVector3 normalize() const
|
||||
{
|
||||
float len = length();
|
||||
if(len != 0) len = static_cast<float>(1.0/len);
|
||||
return RVector3(x*len,y*len,z*len);
|
||||
}
|
||||
|
||||
inline RVector3 interpolatePosition(const RVector3 &b, float pos) const
|
||||
{
|
||||
float pos2 = 1.0f - pos;
|
||||
return RVector3(x * pos2 + b.x * pos, y * pos2 + b.y * pos, z * pos2 + b.z * pos);
|
||||
}
|
||||
|
||||
inline RVector3 interpolateDirection(const RVector3 &b,float pos) const
|
||||
{
|
||||
//float pos2 = 1.0f - pos;
|
||||
|
||||
float dot = scalar(b);
|
||||
if (dot > 0.9995 || dot < -0.9995)
|
||||
return interpolatePosition(b,pos); // cases cause trouble, use linear interpolation here
|
||||
|
||||
float theta = acos(dot) * pos; // interpolated position
|
||||
float st = sin(theta);
|
||||
RVector3 t(b);
|
||||
t -= scale(dot);
|
||||
float lengthSq = t.lengthSquared();
|
||||
float dl = st * ((lengthSq < 0.0001f) ? 1.0f : 1.0f / sqrt(lengthSq));
|
||||
t.scaleIntern(dl);
|
||||
t += scale(cos(theta));
|
||||
return t.normalize();
|
||||
}
|
||||
};
|
||||
inline RVector3 operator+(RVector3 lhs, const RVector3& rhs) // first arg by value, second by const ref
|
||||
{
|
||||
lhs.x += rhs.x;
|
||||
lhs.y += rhs.y;
|
||||
lhs.z += rhs.z;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline RVector3 operator-(RVector3 lhs, const RVector3& rhs) // first arg by value, second by const ref
|
||||
{
|
||||
lhs.x -= rhs.x;
|
||||
lhs.y -= rhs.y;
|
||||
lhs.z -= rhs.z;
|
||||
return lhs;
|
||||
}
|
||||
|
||||
inline RVector3 operator*(const RVector3 &lhs,float rhs) {
|
||||
return lhs.scale(rhs);
|
||||
}
|
||||
|
||||
inline RVector3 operator*(float lhs,const RVector3 &rhs) {
|
||||
return rhs.scale(lhs);
|
||||
}
|
||||
extern const uint8 osAnalogInputChannels[] PROGMEM;
|
||||
//extern uint8 osAnalogInputCounter[ANALOG_INPUTS];
|
||||
//extern uint osAnalogInputBuildup[ANALOG_INPUTS];
|
||||
//extern uint8 osAnalogInputPos; // Current sampling position
|
||||
#if ANALOG_INPUTS > 0
|
||||
extern volatile uint osAnalogInputValues[ANALOG_INPUTS];
|
||||
extern uint8_t pwm_pos[NUM_EXTRUDER+3]; // 0-NUM_EXTRUDER = Heater 0-NUM_EXTRUDER of extruder, NUM_EXTRUDER = Heated bed, NUM_EXTRUDER+1 Board fan, NUM_EXTRUDER+2 = Fan
|
||||
#endif
|
||||
#define PWM_HEATED_BED NUM_EXTRUDER
|
||||
#define PWM_BOARD_FAN PWM_HEATED_BED+1
|
||||
#define PWM_FAN1 PWM_BOARD_FAN+1
|
||||
#define PWM_FAN2 PWM_FAN1+1
|
||||
#define PWM_FAN_THERMO PWM_FAN2+1
|
||||
#define NUM_PWM PWM_FAN_THERMO+1
|
||||
extern uint8_t pwm_pos[NUM_PWM]; // 0-NUM_EXTRUDER = Heater 0-NUM_EXTRUDER of extruder, NUM_EXTRUDER = Heated bed, NUM_EXTRUDER+1 Board fan, NUM_EXTRUDER+2 = Fan
|
||||
#if USE_ADVANCE
|
||||
#if ENABLE_QUADRATIC_ADVANCE
|
||||
extern int maxadv;
|
||||
|
@ -511,20 +918,20 @@ extern void microstepInit();
|
|||
#include "Printer.h"
|
||||
#include "motion.h"
|
||||
extern long baudrate;
|
||||
#if OS_ANALOG_INPUTS>0
|
||||
// Get last result for pin x
|
||||
extern volatile uint osAnalogInputValues[OS_ANALOG_INPUTS];
|
||||
#endif
|
||||
|
||||
#include "HAL.h"
|
||||
|
||||
|
||||
extern unsigned int counterPeriodical;
|
||||
extern volatile uint8_t executePeriodical;
|
||||
extern uint8_t counter250ms;
|
||||
extern uint8_t counter500ms;
|
||||
extern void writeMonitor();
|
||||
#if FEATURE_FAN_CONTROL
|
||||
extern uint8_t fanKickstart;
|
||||
|
||||
#endif
|
||||
#if FEATURE_FAN2_CONTROL
|
||||
extern uint8_t fan2Kickstart;
|
||||
#endif
|
||||
|
||||
#if SDSUPPORT
|
||||
extern char tempLongFilename[LONG_FILENAME_LENGTH+1];
|
||||
|
@ -533,69 +940,69 @@ extern char fullName[LONG_FILENAME_LENGTH*SD_MAX_FOLDER_DEPTH+SD_MAX_FOLDER_DEPT
|
|||
#include "SdFat.h"
|
||||
|
||||
enum LsAction {LS_SerialPrint,LS_Count,LS_GetFilename};
|
||||
class SDCard {
|
||||
class SDCard
|
||||
{
|
||||
public:
|
||||
SdFat fat;
|
||||
//Sd2Card card; // ~14 Byte
|
||||
//SdVolume volume;
|
||||
//SdFile root;
|
||||
//SdFile dir[SD_MAX_FOLDER_DEPTH+1];
|
||||
SdFile file;
|
||||
uint32_t filesize;
|
||||
uint32_t sdpos;
|
||||
//char fullName[13*SD_MAX_FOLDER_DEPTH+13]; // Fill name
|
||||
char *shortname; // Pointer to start of filename itself
|
||||
char *pathend; // File to char where pathname in fullname ends
|
||||
uint8_t sdmode; // true if we are printing from sd card, 2 = stop accepting new commands
|
||||
bool sdactive;
|
||||
//int16_t n;
|
||||
bool savetosd;
|
||||
SdBaseFile parentFound;
|
||||
//Davinci Specific
|
||||
#ifdef SDEEPROM
|
||||
#define SD_EEPROM_FILENAME "eeprom.bin"
|
||||
char * eepromBuffer;
|
||||
uint32_t eepromSize;
|
||||
SdFile eepromFile;
|
||||
inline void setupEeprom(char * buffer, uint32_t size) {
|
||||
eepromBuffer = buffer;
|
||||
eepromSize = size;
|
||||
};
|
||||
bool syncEeprom();
|
||||
SdFat fat;
|
||||
//Sd2Card card; // ~14 Byte
|
||||
//SdVolume volume;
|
||||
//SdFile root;
|
||||
//SdFile dir[SD_MAX_FOLDER_DEPTH+1];
|
||||
SdFile file;
|
||||
#if JSON_OUTPUT
|
||||
GCodeFileInfo fileInfo;
|
||||
#endif
|
||||
uint32_t filesize;
|
||||
uint32_t sdpos;
|
||||
//char fullName[13*SD_MAX_FOLDER_DEPTH+13]; // Fill name
|
||||
char *shortname; // Pointer to start of filename itself
|
||||
char *pathend; // File to char where pathname in fullname ends
|
||||
uint8_t sdmode; // true if we are printing from sd card, 2 = stop accepting new commands
|
||||
bool sdactive;
|
||||
//int16_t n;
|
||||
bool savetosd;
|
||||
SdBaseFile parentFound;
|
||||
|
||||
SDCard();
|
||||
void initsd();
|
||||
//Davinci Specific, SD Card Initialisation and autoprint are separated
|
||||
void autoPrint();
|
||||
void writeCommand(GCode *code);
|
||||
bool selectFile(const char *filename,bool silent=false);
|
||||
void mount();
|
||||
void unmount();
|
||||
void startPrint();
|
||||
void pausePrint(bool intern = false);
|
||||
void continuePrint(bool intern = false);
|
||||
void stopPrint();
|
||||
inline void setIndex(uint32_t newpos) { if(!sdactive) return; sdpos = newpos;file.seekSet(sdpos);}
|
||||
void printStatus();
|
||||
void ls();
|
||||
void startWrite(char *filename);
|
||||
void deleteFile(char *filename);
|
||||
void finishWrite();
|
||||
char *createFilename(char *buffer,const dir_t &p);
|
||||
void makeDirectory(char *filename);
|
||||
bool showFilename(const uint8_t *name);
|
||||
//Davinci Specific, to have clean list and avoid user to delete EEPROM
|
||||
#if HIDE_BINARY_ON_SD
|
||||
static bool showFilename( dir_t*p,const char *filename);
|
||||
#endif
|
||||
void automount();
|
||||
SDCard();
|
||||
void initsd();
|
||||
void writeCommand(GCode *code);
|
||||
bool selectFile(const char *filename,bool silent=false);
|
||||
void mount();
|
||||
void unmount();
|
||||
void startPrint();
|
||||
void pausePrint(bool intern = false);
|
||||
void continuePrint(bool intern = false);
|
||||
void stopPrint();
|
||||
inline void setIndex(uint32_t newpos)
|
||||
{
|
||||
if(!sdactive) return;
|
||||
sdpos = newpos;
|
||||
file.seekSet(sdpos);
|
||||
}
|
||||
void printStatus();
|
||||
void ls();
|
||||
#if JSON_OUTPUT
|
||||
void lsJSON(const char *filename);
|
||||
void JSONFileInfo(const char *filename);
|
||||
static void printEscapeChars(const char *s);
|
||||
#endif
|
||||
void startWrite(char *filename);
|
||||
void deleteFile(char *filename);
|
||||
void finishWrite();
|
||||
char *createFilename(char *buffer,const dir_t &p);
|
||||
void makeDirectory(char *filename);
|
||||
bool showFilename(const uint8_t *name);
|
||||
//Davinci Specific, to have clean list and avoid user to delete EEPROM
|
||||
#if HIDE_BINARY_ON_SD
|
||||
static bool showFilename( dir_t*p,const char *filename);
|
||||
#endif
|
||||
void automount();
|
||||
#ifdef GLENN_DEBUG
|
||||
void writeToFile();
|
||||
void writeToFile();
|
||||
#endif
|
||||
private:
|
||||
uint8_t lsRecursive(SdBaseFile *parent,uint8_t level,char *findFilename);
|
||||
// SdFile *getDirectory(char* name);
|
||||
uint8_t lsRecursive(SdBaseFile *parent,uint8_t level,char *findFilename);
|
||||
// SdFile *getDirectory(char* name);
|
||||
};
|
||||
|
||||
extern SDCard sd;
|
||||
|
@ -631,4 +1038,11 @@ extern int debugWaitLoop;
|
|||
#define SQRT(x) sqrt(x)
|
||||
#endif
|
||||
|
||||
#include "Drivers.h"
|
||||
|
||||
#include "Events.h"
|
||||
#if defined(CUSTOM_EVENTS)
|
||||
#include "CustomEvents.h"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -39,7 +39,7 @@ Implemented Codes
|
|||
- G0 -> G1
|
||||
- G1 - Coordinated Movement X Y Z E, S1 disables boundary check, S0 enables it
|
||||
- G4 - Dwell S<seconds> or P<milliseconds>
|
||||
- G10 S<1 = long retract, 0 = short retract = default> retracts filament accoridng to stored setting
|
||||
- G10 S<1 = long retract, 0 = short retract = default> retracts filament according to stored setting
|
||||
- G11 S<1 = long retract, 0 = short retract = default> = Undo retraction according to stored setting
|
||||
- G20 - Units for G0/G1 are inches.
|
||||
- G21 - Units for G0/G1 are mm.
|
||||
|
@ -47,26 +47,51 @@ Implemented Codes
|
|||
- G29 S<0..2> - Z-Probe at the 3 defined probe points. S = 1 measure avg. zHeight, S = 2 store avg zHeight
|
||||
- G30 P<0..3> - Single z-probe at current position P = 1 first measurement, P = 2 Last measurement P = 0 or 3 first and last measurement
|
||||
- G31 - Write signal of probe sensor
|
||||
- G32 S<0..2> P<0..1> - Autolevel print bed. S = 1 measure zLength, S = 2 Measue and store new zLength
|
||||
- G32 S<0..2> P<0..1> - Autolevel print bed. S = 1 measure zLength, S = 2 Measure and store new zLength
|
||||
- G90 - Use absolute coordinates
|
||||
- G91 - Use relative coordinates
|
||||
- G92 - Set current position to cordinates given
|
||||
- G92 - Set current position to coordinates given
|
||||
- G131 - set extruder offset position to 0 - needed for calibration with G132
|
||||
- G132 - calibrate endstop positions. Call this, after calling G131 and after centering the extruder holder.
|
||||
- G133 - measure steps until max endstops for deltas. Can be used to detect lost steps within tolerances of endstops.
|
||||
- G134 Px Sx Zx - Calibrate nozzle height difference (need z probe in nozzle!) Px = reference extruder, Sx = only measure extrude x against reference, Zx = add to measured z distance for Sx for correction.
|
||||
- G201 P<motorId> X<pos> F<feedrate> - Go to position X with motor X at feedrate F, F is saved so can be used once and alone
|
||||
- G202 P<motorId> X<setpos> - Mark current position as X
|
||||
- G203 P<motorId> - Report current motor position
|
||||
- G204 P<motorId> S<0/1> - Enable/disable motor
|
||||
|
||||
- T0 - select extruder 1
|
||||
- T1 - select extruder 2
|
||||
|
||||
Davinci AiO codes for Horus usage
|
||||
- G201 Fnnn : motor speed
|
||||
- G201 Xnnn : move motor in mm
|
||||
- G201 Ennn : move motor in deg
|
||||
- G50 : reset motor origin position
|
||||
- M17 : motor_disable
|
||||
- M18 : motor_enable
|
||||
- M19 : motor home
|
||||
- M70 Tn : switch off laser n, 0 index based
|
||||
- M71 Tn : switch on laser n, 0 index based
|
||||
- M72 Tn : switch off white led n, 0 index based
|
||||
- M73 Tn : switch on white led n, 0 index based
|
||||
- M60 Tn : read ldr sensor, actually fake as always return 500
|
||||
|
||||
RepRap M Codes
|
||||
|
||||
- M104 - Set extruder target temp
|
||||
- M105 - Read current temp
|
||||
- M106 - Fan on (only if repurpose fan is enabled)
|
||||
- M107 - Fan off (only if repurpose fan is enabled)
|
||||
M106/M107 work only if repurpose fan is enabled, as by default fan is managed by temperature
|
||||
- M106 S<speed> P<fan> - Fan on speed = 0..255, P = 0 or 1, 0 is default and can be omitted
|
||||
- M107 P<fan> - Fan off, P = 0 or 1, 0 is default and can be omitted
|
||||
- M109 - Wait for extruder current temp to reach target temp.
|
||||
- M114 - Display current position
|
||||
- M114 S1 - Display current position, S1 = also write position in steps
|
||||
|
||||
Custom M Codes
|
||||
|
||||
- M3 - Spindle on, Clockwise or Laser on during G1 moves.
|
||||
- M4 - Spindle on, Counterclockwise.
|
||||
- M5 - Spindle off, Laser off.
|
||||
- M20 - List SD card
|
||||
- M21 - Init SD card
|
||||
- M22 - Release SD card
|
||||
|
@ -88,12 +113,14 @@ Custom M Codes
|
|||
- M84 - Disable steppers until next move,
|
||||
or use S<seconds> to specify an inactivity timeout, after which the steppers will be disabled. S0 to disable the timeout.
|
||||
- M85 - Set inactivity shutdown timer with parameter S<seconds>. To disable set zero (default)
|
||||
- M92 - Set axisStepsPerMM - same syntax as G1
|
||||
- M92 - Set axisStepsPerMM - same syntax as G92
|
||||
- M99 S<delayInSec> X0 Y0 Z0 - Disable motors for S seconds (default 10) for given axis.
|
||||
- M100 T<extruderNum> clean nozzle, no extruder specified clean all available
|
||||
- M104 S<temp> T<extruder> P1 F1 - Set temperature without wait. P1 = wait for moves to finish, F1 = beep when temp. reached first time
|
||||
- M105 X0 - Get temperatures. If X0 is added, the raw analog values are also written.
|
||||
--M110 - Reset line number
|
||||
- M112 - Emergency kill
|
||||
--M114 - print positions
|
||||
- M115- Capabilities string
|
||||
- M116 - Wait for all temperatures in a +/- 1 degree range
|
||||
- M117 <message> - Write message in status row on lcd
|
||||
|
@ -113,17 +140,18 @@ Custom M Codes
|
|||
- M209 S<0/1> - Enable/disable autoretraction
|
||||
- M220 S<Feedrate multiplier in percent> - Increase/decrease given feedrate
|
||||
- M221 S<Extrusion flow multiplier in percent> - Increase/decrease given flow rate
|
||||
- M226 P<pin> S<state 0/1> - Wait for pin getting state S. Add X0 to init as input without pullup and X1 for input with pullup.
|
||||
- M231 S<OPS_MODE> X<Min_Distance> Y<Retract> Z<Backlash> F<ReatrctMove> - Set OPS parameter
|
||||
- M232 - Read and reset max. advance values
|
||||
- M233 X<AdvanceK> Y<AdvanceL> - Set temporary advance K-value to X and linear term advanceL to Y
|
||||
- M251 Measure Z steps from homing stop (Delta printers). S0 - Reset, S1 - Print, S2 - Store to Z length (also EEPROM if enabled)
|
||||
- M280 S<mode> - Set ditto printing mode. mode: 0 = off, 1 = 1 extra extruder, 2 = 2 extra extruder, 3 = 3 extra extruders
|
||||
- M281 Test if watchdog is running and working.
|
||||
- M281 Test if watchdog is running and working. Use M281 X0 to disable watchdog on AVR boards. Sometimes needed for boards with old bootloaders to allow reflashing.
|
||||
- M300 S<Frequency> P<DurationMillis> play frequency
|
||||
- M302 S<0 or 1> - allow cold extrusion. Without S parameter it will allow. S1 will disallow.
|
||||
- M303 P<extruder/bed> S<printTemerature> X0 R<Repetitions>- Autodetect pid values. Use P<NUM_EXTRUDER> for heated bed. X0 saves result in EEPROM. R is number of cycles.
|
||||
- M320 - Activate autolevel
|
||||
- M321 - Deactivate autolevel
|
||||
- M320 S<0/1> - Activate autolevel, S1 stores it in eeprom
|
||||
- M321 S<0/1> - Deactivate autolevel, S1 stores it in eeprom
|
||||
- M322 - Reset autolevel matrix
|
||||
- M323 S0/S1 enable disable distortion correction P0 = not permanent, P1 = permanent = default
|
||||
- M340 P<servoId> S<pulseInUS> R<autoOffIn ms>: servoID = 0..3, Servos are controlled by a pulse with normally between 500 and 2500 with 1500ms in center position. 0 turns servo off. R allows automatic disabling after a while.
|
||||
|
@ -132,7 +160,12 @@ Custom M Codes
|
|||
- M360 - show configuration
|
||||
- M400 - Wait until move buffers empty.
|
||||
- M401 - Store x, y and z position.
|
||||
- M402 - Go to stored position. If X, Y or Z is specified, only these coordinates are used. F changes feedrate fo rthat move.
|
||||
- M402 - Go to stored position. If X, Y or Z is specified, only these coordinates are used. F changes feedrate for that move.
|
||||
- M450 - Reports printer mode
|
||||
- M451 - Set printer mode to FFF
|
||||
- M452 - Set printer mode to laser
|
||||
- M453 - Set printer mode to CNC
|
||||
- M460 X<minTemp> Y<maxTemp> : Set temperature range for thermistor controlled fan
|
||||
- M500 Store settings to EEPROM
|
||||
- M501 Load settings from EEPROM
|
||||
- M502 Reset settings to the one in configuration.h. Does not store values in EEPROM!
|
||||
|
@ -140,7 +173,10 @@ Custom M Codes
|
|||
- M600 Change filament
|
||||
- M601 S<1/0> - Pause extruders. Paused extrudes disable heaters and motor. Unpausing reheats extruder to old temp.
|
||||
- M602 S<1/0> P<1/0>- Debug jam control (S) Disable jam control (P). If enabled it will log signal changes and will not trigger jam errors!
|
||||
- M603 - Simulate a jam
|
||||
- M604 X<slowdownSteps> Y<errorSteps> Z<slowdownTo> T<extruderId> - Set jam detection values on a per extruder basis. If not set it uses defaults from Configuration.h
|
||||
- M908 P<address> S<value> : Set stepper current for digipot (RAMBO board)
|
||||
- M999 - Continue from fatal error. M999 S1 will create a fatal error for testing.
|
||||
*/
|
||||
|
||||
#include "Repetier.h"
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
*/
|
||||
|
||||
#include "Repetier.h"
|
||||
#include "ui.h"
|
||||
|
||||
#if SDSUPPORT
|
||||
|
||||
|
@ -42,27 +41,26 @@ void SDCard::automount()
|
|||
#if SDCARDDETECT > -1
|
||||
if(READ(SDCARDDETECT) != SDCARDDETECTINVERTED)
|
||||
{
|
||||
if(sdactive) // Card removed
|
||||
if(sdactive || sdmode == 100) // Card removed
|
||||
{
|
||||
Com::printFLN(PSTR("SD card removed"));
|
||||
#if UI_DISPLAY_TYPE != NO_DISPLAY
|
||||
uid.executeAction(UI_ACTION_TOP_MENU, true);
|
||||
#endif
|
||||
unmount();
|
||||
UI_STATUS(UI_TEXT_SD_REMOVED);
|
||||
UI_STATUS_UPD_F(Com::translatedF(UI_TEXT_SD_REMOVED_ID));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!sdactive)
|
||||
if(!sdactive && sdmode != 100)
|
||||
{
|
||||
UI_STATUS(UI_TEXT_SD_INSERTED);
|
||||
Com::printFLN(PSTR("SD card inserted")); // Not translateable or host will not understand signal
|
||||
initsd();
|
||||
//Davinci Specific, init and autoprint are separated
|
||||
autoPrint();
|
||||
UI_STATUS_UPD_F(Com::translatedF(UI_TEXT_SD_INSERTED_ID));
|
||||
mount();
|
||||
if(sdmode != 100) // send message only if we have success
|
||||
Com::printFLN(PSTR("SD card inserted")); // Not translatable or host will not understand signal
|
||||
#if UI_DISPLAY_TYPE != NO_DISPLAY
|
||||
if(sdactive) {
|
||||
if(sdactive && !uid.isWizardActive()) { // Wizards have priority
|
||||
Printer::setAutomount(true);
|
||||
uid.executeAction(UI_ACTION_SD_PRINT + UI_ACTION_TOPMENU, true);
|
||||
}
|
||||
|
@ -80,52 +78,28 @@ void SDCard::initsd()
|
|||
if(READ(SDCARDDETECT) != SDCARDDETECTINVERTED)
|
||||
return;
|
||||
#endif
|
||||
HAL::pingWatchdog();
|
||||
HAL::delayMilliseconds(50); // wait for stabilization of contacts, bootup ...
|
||||
fat.begin(SDSS, SPI_FULL_SPEED); // dummy init of SD_CARD
|
||||
HAL::delayMilliseconds(50); // wait for init end
|
||||
HAL::pingWatchdog();
|
||||
/*if(dir[0].isOpen())
|
||||
dir[0].close();*/
|
||||
if(!fat.begin(SDSS, SPI_FULL_SPEED))
|
||||
{
|
||||
Com::printFLN(Com::tSDInitFail);
|
||||
sdmode = 100; // prevent automount loop!
|
||||
return;
|
||||
}
|
||||
sdactive = true;
|
||||
Printer::setMenuMode(MENU_MODE_SD_MOUNTED, true);
|
||||
HAL::pingWatchdog();
|
||||
|
||||
fat.chdir();
|
||||
//Davinci Specific,EEPROM is on SD Card
|
||||
#ifdef SDEEPROM
|
||||
if (eepromBuffer != NULL && eepromSize > 0)
|
||||
{
|
||||
if (eepromFile.isOpen())
|
||||
eepromFile.close();
|
||||
if (!eepromFile.open(SD_EEPROM_FILENAME, O_RDWR | O_CREAT | O_SYNC) ||
|
||||
eepromFile.read(eepromBuffer, eepromSize) != eepromSize)
|
||||
{
|
||||
Com::printFLN(Com::tOpenFailedFile, SD_EEPROM_FILENAME);
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#ifdef SDEEPROM
|
||||
bool SDCard::syncEeprom() {
|
||||
if (!sdactive)
|
||||
{
|
||||
if (eepromFile.isOpen())
|
||||
eepromFile.close();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!eepromFile.seekSet(0))
|
||||
return 0;
|
||||
|
||||
return eepromFile.write(eepromBuffer, eepromSize) == eepromSize;
|
||||
}
|
||||
#endif
|
||||
|
||||
void SDCard::autoPrint() {
|
||||
if (!sdactive)
|
||||
return;
|
||||
|
||||
|
||||
#if defined(EEPROM_AVAILABLE) && EEPROM_AVAILABLE == EEPROM_SDCARD
|
||||
HAL::importEEPROM();
|
||||
#endif
|
||||
if(selectFile("init.g", true))
|
||||
{
|
||||
startPrint();
|
||||
|
@ -137,8 +111,6 @@ void SDCard::mount()
|
|||
{
|
||||
sdmode = 0;
|
||||
initsd();
|
||||
//Davinci Specific, Init and autoprint are separated
|
||||
autoPrint();
|
||||
}
|
||||
|
||||
void SDCard::unmount()
|
||||
|
@ -186,7 +158,7 @@ void SDCard::pausePrint(bool intern)
|
|||
Printer::moveToReal(0, 0.9 * EEPROM::deltaMaxRadius(), IGNORE_COORDINATE, IGNORE_COORDINATE, Printer::maxFeedrate[X_AXIS]);
|
||||
#else
|
||||
//Davinci Specific, down bed and pause on Drip Box instead of front
|
||||
if (Printer::lastCmdPos[Z_AXIS]+10<Printer::zMin+Printer::zLength)
|
||||
if (Printer::lastCmdPos[Z_AXIS]+10<Printer::zMin+Printer::zLength)
|
||||
Printer::moveToReal(IGNORE_COORDINATE,IGNORE_COORDINATE,Printer::lastCmdPos[Z_AXIS]+10,IGNORE_COORDINATE,Printer::homingFeedrate[Z_AXIS]);
|
||||
Printer::moveToReal(Printer::xMin,Printer::yMin,IGNORE_COORDINATE,IGNORE_COORDINATE,Printer::homingFeedrate[X_AXIS]);
|
||||
#endif
|
||||
|
@ -198,10 +170,10 @@ void SDCard::continuePrint(bool intern)
|
|||
{
|
||||
if(!sd.sdactive) return;
|
||||
if(intern) {
|
||||
//Davinci Specific, restore extruder for DUO
|
||||
#if NUM_EXTRUDER>1
|
||||
Extruder::selectExtruderById(Printer::lastextruderID);
|
||||
#endif
|
||||
//Davinci Specific, restore extruder for DUO
|
||||
#if NUM_EXTRUDER>1
|
||||
Extruder::selectExtruderById(Printer::lastextruderID);
|
||||
#endif
|
||||
GCode::executeFString(PSTR(PAUSE_END_COMMANDS));
|
||||
Printer::GoToMemoryPosition(true, true, false, false, Printer::maxFeedrate[X_AXIS]);
|
||||
Printer::GoToMemoryPosition(false, false, true, false, Printer::maxFeedrate[Z_AXIS] / 2.0f);
|
||||
|
@ -229,27 +201,31 @@ void SDCard::stopPrint()
|
|||
|
||||
void SDCard::writeCommand(GCode *code)
|
||||
{
|
||||
unsigned int sum1=0,sum2=0; // for fletcher-16 checksum
|
||||
unsigned int sum1 = 0, sum2 = 0; // for fletcher-16 checksum
|
||||
uint8_t buf[100];
|
||||
uint8_t p=2;
|
||||
uint8_t p = 2;
|
||||
file.writeError = false;
|
||||
int params = 128 | (code->params & ~1);
|
||||
*(int*)buf = params;
|
||||
uint16_t params = 128 | (code->params & ~1);
|
||||
memcopy2(buf,¶ms);
|
||||
//*(int*)buf = params;
|
||||
if(code->isV2()) // Read G,M as 16 bit value
|
||||
{
|
||||
*(int*)&buf[p] = code->params2;
|
||||
p+=2;
|
||||
memcopy2(&buf[p],&code->params2);
|
||||
//*(int*)&buf[p] = code->params2;
|
||||
p += 2;
|
||||
if(code->hasString())
|
||||
buf[p++] = strlen(code->text);
|
||||
if(code->hasM())
|
||||
{
|
||||
*(int*)&buf[p] = code->M;
|
||||
p+=2;
|
||||
memcopy2(&buf[p],&code->M);
|
||||
//*(int*)&buf[p] = code->M;
|
||||
p += 2;
|
||||
}
|
||||
if(code->hasG())
|
||||
{
|
||||
*(int*)&buf[p]= code->G;
|
||||
p+=2;
|
||||
memcopy2(&buf[p],&code->G);
|
||||
//*(int*)&buf[p]= code->G;
|
||||
p += 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -265,28 +241,33 @@ void SDCard::writeCommand(GCode *code)
|
|||
}
|
||||
if(code->hasX())
|
||||
{
|
||||
*(float*)&buf[p] = code->X;
|
||||
p+=4;
|
||||
memcopy4(&buf[p],&code->X);
|
||||
//*(float*)&buf[p] = code->X;
|
||||
p += 4;
|
||||
}
|
||||
if(code->hasY())
|
||||
{
|
||||
*(float*)&buf[p] = code->Y;
|
||||
p+=4;
|
||||
memcopy4(&buf[p],&code->Y);
|
||||
//*(float*)&buf[p] = code->Y;
|
||||
p += 4;
|
||||
}
|
||||
if(code->hasZ())
|
||||
{
|
||||
*(float*)&buf[p] = code->Z;
|
||||
p+=4;
|
||||
memcopy4(&buf[p],&code->Z);
|
||||
//*(float*)&buf[p] = code->Z;
|
||||
p += 4;
|
||||
}
|
||||
if(code->hasE())
|
||||
{
|
||||
*(float*)&buf[p] = code->E;
|
||||
p+=4;
|
||||
memcopy4(&buf[p],&code->E);
|
||||
//*(float*)&buf[p] = code->E;
|
||||
p += 4;
|
||||
}
|
||||
if(code->hasF())
|
||||
{
|
||||
*(float*)&buf[p] = code->F;
|
||||
p+=4;
|
||||
memcopy4(&buf[p],&code->F);
|
||||
//*(float*)&buf[p] = code->F;
|
||||
p += 4;
|
||||
}
|
||||
if(code->hasT())
|
||||
{
|
||||
|
@ -294,23 +275,81 @@ void SDCard::writeCommand(GCode *code)
|
|||
}
|
||||
if(code->hasS())
|
||||
{
|
||||
*(long int*)&buf[p] = code->S;
|
||||
p+=4;
|
||||
memcopy4(&buf[p],&code->S);
|
||||
//*(int32_t*)&buf[p] = code->S;
|
||||
p += 4;
|
||||
}
|
||||
if(code->hasP())
|
||||
{
|
||||
*(long int*)&buf[p] = code->P;
|
||||
p+=4;
|
||||
memcopy4(&buf[p],&code->P);
|
||||
//*(int32_t*)&buf[p] = code->P;
|
||||
p += 4;
|
||||
}
|
||||
if(code->hasI())
|
||||
{
|
||||
*(float*)&buf[p] = code->I;
|
||||
p+=4;
|
||||
memcopy4(&buf[p],&code->I);
|
||||
//*(float*)&buf[p] = code->I;
|
||||
p += 4;
|
||||
}
|
||||
if(code->hasJ())
|
||||
{
|
||||
*(float*)&buf[p] = code->J;
|
||||
p+=4;
|
||||
memcopy4(&buf[p],&code->J);
|
||||
//*(float*)&buf[p] = code->J;
|
||||
p += 4;
|
||||
}
|
||||
if(code->hasR())
|
||||
{
|
||||
memcopy4(&buf[p],&code->R);
|
||||
//*(float*)&buf[p] = code->R;
|
||||
p += 4;
|
||||
}
|
||||
if(code->hasD())
|
||||
{
|
||||
memcopy4(&buf[p],&code->D);
|
||||
//*(float*)&buf[p] = code->D;
|
||||
p += 4;
|
||||
}
|
||||
if(code->hasC())
|
||||
{
|
||||
memcopy4(&buf[p],&code->C);
|
||||
//*(float*)&buf[p] = code->C;
|
||||
p += 4;
|
||||
}
|
||||
if(code->hasH())
|
||||
{
|
||||
memcopy4(&buf[p],&code->H);
|
||||
//*(float*)&buf[p] = code->H;
|
||||
p += 4;
|
||||
}
|
||||
if(code->hasA())
|
||||
{
|
||||
memcopy4(&buf[p],&code->A);
|
||||
//*(float*)&buf[p] = code->A;
|
||||
p += 4;
|
||||
}
|
||||
if(code->hasB())
|
||||
{
|
||||
memcopy4(&buf[p],&code->B);
|
||||
//*(float*)&buf[p] = code->B;
|
||||
p += 4;
|
||||
}
|
||||
if(code->hasK())
|
||||
{
|
||||
memcopy4(&buf[p],&code->K);
|
||||
//*(float*)&buf[p] = code->K;
|
||||
p += 4;
|
||||
}
|
||||
if(code->hasL())
|
||||
{
|
||||
memcopy4(&buf[p],&code->L);
|
||||
//*(float*)&buf[p] = code->L;
|
||||
p += 4;
|
||||
}
|
||||
if(code->hasO())
|
||||
{
|
||||
memcopy4(&buf[p],&code->O);
|
||||
//*(float*)&buf[p] = code->O;
|
||||
p += 4;
|
||||
}
|
||||
if(code->hasString()) // read 16 uint8_t into string
|
||||
{
|
||||
|
@ -322,7 +361,7 @@ void SDCard::writeCommand(GCode *code)
|
|||
}
|
||||
else
|
||||
{
|
||||
for(uint8_t i=0; i<16; ++i) buf[p++] = *sp++;
|
||||
for(uint8_t i = 0; i < 16; ++i) buf[p++] = *sp++;
|
||||
}
|
||||
}
|
||||
uint8_t *ptr = buf;
|
||||
|
@ -334,14 +373,19 @@ void SDCard::writeCommand(GCode *code)
|
|||
do
|
||||
{
|
||||
sum1 += *ptr++;
|
||||
if(sum1>=255) sum1-=255;
|
||||
if(sum1 >= 255) sum1 -= 255;
|
||||
sum2 += sum1;
|
||||
if(sum2>=255) sum2-=255;
|
||||
if(sum2 >= 255) sum2 -= 255;
|
||||
}
|
||||
while (--tlen);
|
||||
}
|
||||
buf[p++] = sum1;
|
||||
buf[p++] = sum2;
|
||||
// Debug
|
||||
/*Com::printF(PSTR("Buf: "));
|
||||
for(int i=0;i<p;i++)
|
||||
Com::printF(PSTR(" "),(int)buf[i]);
|
||||
Com::println();*/
|
||||
if(params == 128)
|
||||
{
|
||||
Com::printErrorFLN(Com::tAPIDFinished);
|
||||
|
@ -387,11 +431,11 @@ bool SDCard::showFilename(dir_t *p,const char *filename)
|
|||
else
|
||||
file_extension[0]=0;
|
||||
//check extension
|
||||
if ((strcasecmp(file_extension,"bin")==0) //all .bin
|
||||
|| (strcasecmp(file_extension,"dat")==0) //all .dat
|
||||
|| (strcasecmp(file_extension,"hex")==0) //all .hex
|
||||
|| (strchr(filename,'.')==NULL)) return false; //all file without extension
|
||||
}
|
||||
if ((strcasecmp(file_extension,"bin")==0) //all .bin
|
||||
|| (strcasecmp(file_extension,"dat")==0) //all .dat
|
||||
|| (strcasecmp(file_extension,"hex")==0) //all .hex
|
||||
|| (strchr(filename,'.')==NULL)) return false; //all file without extension
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
@ -427,11 +471,97 @@ void SDCard::ls()
|
|||
Com::printFLN(Com::tEndFileList);
|
||||
}
|
||||
|
||||
#if JSON_OUTPUT
|
||||
void SDCard::lsJSON(const char *filename)
|
||||
{
|
||||
SdBaseFile dir;
|
||||
fat.chdir();
|
||||
if (*filename == 0) {
|
||||
dir.openRoot(fat.vol());
|
||||
} else {
|
||||
if (!dir.open(fat.vwd(), filename, O_READ) || !dir.isDir()) {
|
||||
Com::printF(Com::tJSONErrorStart);
|
||||
Com::printF(Com::tFileOpenFailed);
|
||||
Com::printFLN(Com::tJSONErrorEnd);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Com::printF(Com::tJSONDir);
|
||||
SDCard::printEscapeChars(filename);
|
||||
Com::printF(Com::tJSONFiles);
|
||||
dir.lsJSON();
|
||||
Com::printFLN(Com::tJSONArrayEnd);
|
||||
}
|
||||
|
||||
void SDCard::printEscapeChars(const char *s) {
|
||||
for (unsigned int i = 0; i < strlen(s); ++i) {
|
||||
switch (s[i]) {
|
||||
case '"':
|
||||
case '/':
|
||||
case '\b':
|
||||
case '\f':
|
||||
case '\n':
|
||||
case '\r':
|
||||
case '\t':
|
||||
case '\\':
|
||||
Com::print('\\');
|
||||
break;
|
||||
}
|
||||
Com::print(s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void SDCard::JSONFileInfo(const char* filename) {
|
||||
SdBaseFile targetFile;
|
||||
GCodeFileInfo *info,tmpInfo;
|
||||
if (strlen(filename) == 0) {
|
||||
targetFile = file;
|
||||
info = &fileInfo;
|
||||
} else {
|
||||
if (!targetFile.open(fat.vwd(), filename, O_READ) || targetFile.isDir()) {
|
||||
Com::printF(Com::tJSONErrorStart);
|
||||
Com::printF(Com::tFileOpenFailed);
|
||||
Com::printFLN(Com::tJSONErrorEnd);
|
||||
return;
|
||||
}
|
||||
info = &tmpInfo;
|
||||
info->init(targetFile);
|
||||
}
|
||||
if (!targetFile.isOpen()) {
|
||||
Com::printF(Com::tJSONErrorStart);
|
||||
Com::printF(Com::tNotSDPrinting);
|
||||
Com::printFLN(Com::tJSONErrorEnd);
|
||||
return;
|
||||
}
|
||||
|
||||
// {"err":0,"size":457574,"height":4.00,"layerHeight":0.25,"filament":[6556.3],"generatedBy":"Slic3r 1.1.7 on 2014-11-09 at 17:11:32"}
|
||||
Com::printF(Com::tJSONFileInfoStart);
|
||||
Com::print(info->fileSize);
|
||||
Com::printF(Com::tJSONFileInfoHeight);
|
||||
Com::print(info->objectHeight);
|
||||
Com::printF(Com::tJSONFileInfoLayerHeight);
|
||||
Com::print(info->layerHeight);
|
||||
Com::printF(Com::tJSONFileInfoFilament);
|
||||
Com::print(info->filamentNeeded);
|
||||
Com::printF(Com::tJSONFileInfoGeneratedBy);
|
||||
Com::print(info->generatedBy);
|
||||
Com::print('"');
|
||||
if (strlen(filename) == 0) {
|
||||
Com::printF(Com::tJSONFileInfoName);
|
||||
file.printName();
|
||||
Com::print('"');
|
||||
}
|
||||
Com::print('}');
|
||||
Com::println();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
bool SDCard::selectFile(const char *filename, bool silent)
|
||||
{
|
||||
SdBaseFile parent;
|
||||
const char *oldP = filename;
|
||||
boolean bFound;
|
||||
|
||||
if(!sdactive) return false;
|
||||
sdmode = 0;
|
||||
|
@ -451,6 +581,9 @@ bool SDCard::selectFile(const char *filename, bool silent)
|
|||
Com::printF(Com::tFileOpened, oldP);
|
||||
Com::printFLN(Com::tSpaceSizeColon,file.fileSize());
|
||||
}
|
||||
#if JSON_OUTPUT
|
||||
fileInfo.init(file);
|
||||
#endif
|
||||
sdpos = 0;
|
||||
filesize = file.fileSize();
|
||||
Com::printFLN(Com::tFileSelected);
|
||||
|
@ -489,7 +622,7 @@ void SDCard::startWrite(char *filename)
|
|||
}
|
||||
else
|
||||
{
|
||||
UI_STATUS(UI_TEXT_UPLOADING);
|
||||
UI_STATUS_F(Com::translatedF(UI_TEXT_UPLOADING_ID));
|
||||
savetosd = true;
|
||||
Com::printFLN(Com::tWritingToFile,filename);
|
||||
}
|
||||
|
|
|
@ -32,11 +32,6 @@ extern int8_t RFstrnicmp(const char* s1, const char* s2, size_t n);
|
|||
|
||||
//#define GLENN_DEBUG
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
static void pstrPrint(FSTRINGPARAM(str)) {
|
||||
Com::printF(str);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
static void pstrPrintln(FSTRINGPARAM(str)) {
|
||||
Com::printFLN(str);
|
||||
|
@ -652,11 +647,12 @@ void SdBaseFile::ls(uint8_t flags) {
|
|||
ls(flags, 0);
|
||||
}
|
||||
|
||||
uint8_t SdBaseFile::lsRecursive(SdBaseFile *parent, uint8_t level, char *findFilename, SdBaseFile *pParentFound)
|
||||
uint8_t SdBaseFile::lsRecursive(SdBaseFile *parent, uint8_t level, char *findFilename, SdBaseFile *pParentFound, bool isJson)
|
||||
{
|
||||
dir_t *p = NULL;
|
||||
uint8_t cnt=0;
|
||||
char *oldpathend = pathend;
|
||||
//uint8_t cnt=0;
|
||||
//char *oldpathend = pathend;
|
||||
bool firstFile = true;
|
||||
|
||||
parent->rewind();
|
||||
|
||||
|
@ -665,21 +661,29 @@ uint8_t SdBaseFile::lsRecursive(SdBaseFile *parent, uint8_t level, char *findFil
|
|||
HAL::pingWatchdog();
|
||||
if (! (DIR_IS_FILE(p) || DIR_IS_SUBDIR(p))) continue;
|
||||
if (strcmp(tempLongFilename, "..") == 0) continue;
|
||||
if( DIR_IS_SUBDIR(p))
|
||||
{
|
||||
if(level>=SD_MAX_FOLDER_DEPTH) continue; // can't go deeper
|
||||
if(level<SD_MAX_FOLDER_DEPTH)
|
||||
{
|
||||
if (findFilename == NULL)
|
||||
{
|
||||
if(level)
|
||||
{
|
||||
Com::print(fullName);
|
||||
Com::printF(Com::tSlash);
|
||||
}
|
||||
Com::print(tempLongFilename);
|
||||
Com::printFLN(Com::tSlash); //End with / to mark it as directory entry, so we can see empty directories.
|
||||
if (tempLongFilename[0] == '.') continue; // MAC CRAP
|
||||
if (DIR_IS_SUBDIR(p)) {
|
||||
if (level >= SD_MAX_FOLDER_DEPTH) continue; // can't go deeper
|
||||
if (level < SD_MAX_FOLDER_DEPTH && findFilename == NULL) {
|
||||
if (level && !isJson) {
|
||||
Com::print(fullName);
|
||||
Com::printF(Com::tSlash);
|
||||
}
|
||||
#if JSON_OUTPUT
|
||||
if (isJson) {
|
||||
if (!firstFile) Com::print(',');
|
||||
Com::print('"');Com::print('*');
|
||||
SDCard::printEscapeChars(tempLongFilename);
|
||||
Com::print('"');
|
||||
firstFile = false;
|
||||
} else {
|
||||
Com::print(tempLongFilename);
|
||||
Com::printFLN(Com::tSlash); // End with / to mark it as directory entry, so we can see empty directories.
|
||||
}
|
||||
#else
|
||||
Com::print(tempLongFilename);
|
||||
Com::printFLN(Com::tSlash); // End with / to mark it as directory entry, so we can see empty directories.
|
||||
#endif
|
||||
}
|
||||
SdBaseFile next;
|
||||
char *tmp;
|
||||
|
@ -689,11 +693,11 @@ uint8_t SdBaseFile::lsRecursive(SdBaseFile *parent, uint8_t level, char *findFil
|
|||
strcat(fullName, tempLongFilename);
|
||||
uint16_t index = (parent->curPosition()-31) >> 5;
|
||||
|
||||
if(next.open(parent, index, O_READ))
|
||||
{
|
||||
if (next.lsRecursive(&next,level+1, findFilename, pParentFound))
|
||||
if(!isJson && next.open(parent, index, O_READ))
|
||||
{
|
||||
if (next.lsRecursive(&next,level+1, findFilename, pParentFound,false))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
parent->seekSet(32 * (index + 1));
|
||||
if ((tmp = strrchr(fullName, '/'))!= NULL)
|
||||
*tmp = 0;
|
||||
|
@ -721,16 +725,27 @@ uint8_t SdBaseFile::lsRecursive(SdBaseFile *parent, uint8_t level, char *findFil
|
|||
}
|
||||
else
|
||||
{
|
||||
if(level)
|
||||
if(level && !isJson)
|
||||
{
|
||||
Com::print(fullName);
|
||||
Com::printF(Com::tSlash);
|
||||
}
|
||||
Com::print(tempLongFilename);
|
||||
#if SD_EXTENDED_DIR
|
||||
Com::printF(Com::tSpace,(long)p->fileSize);
|
||||
#if JSON_OUTPUT
|
||||
if (isJson) {
|
||||
if (!firstFile) Com::printF(Com::tComma);
|
||||
Com::print('"');
|
||||
SDCard::printEscapeChars(tempLongFilename);
|
||||
Com::print('"');
|
||||
firstFile = false;
|
||||
} else
|
||||
#endif
|
||||
Com::println();
|
||||
{
|
||||
Com::print(tempLongFilename);
|
||||
#if SD_EXTENDED_DIR
|
||||
Com::printF(Com::tSpace, (long) p->fileSize);
|
||||
#endif
|
||||
Com::println();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -754,20 +769,30 @@ uint8_t SdBaseFile::lsRecursive(SdBaseFile *parent, uint8_t level, char *findFil
|
|||
* list to indicate subdirectory level.
|
||||
*/
|
||||
void SdBaseFile::ls(uint8_t flags, uint8_t indent) {
|
||||
SdBaseFile parent;
|
||||
|
||||
rewind();
|
||||
SdBaseFile parent;
|
||||
rewind();
|
||||
*fullName = 0;
|
||||
pathend = fullName;
|
||||
parent = *this;
|
||||
lsRecursive(&parent, 0, NULL, NULL);
|
||||
pathend = fullName;
|
||||
parent = *this;
|
||||
lsRecursive(&parent, 0, NULL, NULL, false);
|
||||
}
|
||||
|
||||
#if JSON_OUTPUT
|
||||
void SdBaseFile::lsJSON() {
|
||||
SdBaseFile parent;
|
||||
rewind();
|
||||
*fullName = 0;
|
||||
parent = *this;
|
||||
lsRecursive(&parent, 0, NULL, NULL, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// saves 32 bytes on stack for ls recursion
|
||||
// return 0 - EOF, 1 - normal file, or 2 - directory
|
||||
int8_t SdBaseFile::lsPrintNext(uint8_t flags, uint8_t indent) {
|
||||
dir_t dir;
|
||||
uint8_t w = 0;
|
||||
//uint8_t w = 0;
|
||||
while (1) {
|
||||
if (read(&dir, sizeof(dir)) != sizeof(dir)) return 0;
|
||||
if (dir.name[0] == DIR_NAME_FREE) return 0;
|
||||
|
@ -876,8 +901,6 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const char* path, bool pFlag) {
|
|||
{
|
||||
return mkdir(&newParent, dname);
|
||||
}
|
||||
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -886,13 +909,13 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t *dname) {
|
|||
|
||||
if (!parent->isDir()) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
return false;
|
||||
}
|
||||
|
||||
// create a normal file
|
||||
if (!open(parent, dname, O_CREAT | O_EXCL | O_RDWR, true)) {
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
return false;
|
||||
}
|
||||
|
||||
// make entry for '.'
|
||||
|
@ -908,7 +931,7 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t *dname) {
|
|||
for (uint8_t i = 1; i < 11; i++) d.name[i] = ' ';
|
||||
|
||||
if (write(&d, sizeof(dir_t)) < 0)
|
||||
goto fail;
|
||||
return false;
|
||||
sync();
|
||||
|
||||
// make entry for '..'
|
||||
|
@ -921,18 +944,16 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t *dname) {
|
|||
d.firstClusterHigh = parent->firstCluster_ >> 16;
|
||||
}
|
||||
if (write(&d, sizeof(dir_t)) < 0)
|
||||
goto fail;
|
||||
return false;
|
||||
sync();
|
||||
memset(&d, 0, sizeof(dir_t));
|
||||
if (write(&d, sizeof(dir_t)) < 0)
|
||||
goto fail;
|
||||
return false;
|
||||
sync();
|
||||
// fileSize_ = 0;
|
||||
type_ = FAT_FILE_TYPE_SUBDIR;
|
||||
flags_ |= F_FILE_DIR_DIRTY;
|
||||
return true;
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
/** Open a file in the current working directory.
|
||||
|
@ -1005,10 +1026,10 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t *dname) {
|
|||
SdBaseFile *newParent, boolean bMakeDirs) {
|
||||
SdBaseFile dir1, dir2;
|
||||
SdBaseFile *parent = dirFile;
|
||||
dir_t *pEntry;
|
||||
//dir_t *pEntry;
|
||||
SdBaseFile *sub = &dir1;
|
||||
char *p;
|
||||
boolean bFound;
|
||||
//boolean bFound;
|
||||
|
||||
#ifdef GLENN_DEBUG
|
||||
Commands::checkFreeMemory();
|
||||
|
@ -1052,7 +1073,7 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t *dname) {
|
|||
Commands::checkFreeMemory();
|
||||
Commands::writeLowestFreeRAM();
|
||||
#endif
|
||||
bFound = false;
|
||||
//bFound = false;
|
||||
if (!sub->open(parent, dname, O_READ, false))
|
||||
{
|
||||
if (!bMakeDirs)
|
||||
|
@ -1093,7 +1114,6 @@ bool SdBaseFile::open(SdBaseFile* dirFile, const char* path, uint8_t oflag)
|
|||
return open(&parent, dname, oflag, false);
|
||||
}
|
||||
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1113,11 +1133,11 @@ uint8_t SdBaseFile::lfn_checksum(const unsigned char *pFCBName)
|
|||
bool SdBaseFile::open(SdBaseFile* dirFile,const uint8_t *dname, uint8_t oflag, bool bDir) {
|
||||
bool emptyFound = false;
|
||||
uint8_t index = 0;
|
||||
dir_t tempDir, *p;
|
||||
dir_t tempDir, *p = NULL;
|
||||
const char *tempPtr;
|
||||
char newName[SHORT_FILENAME_LENGTH+2];
|
||||
boolean bShortName = false;
|
||||
int8_t cVFATNeeded = -1, wIndex, cVFATFoundCur;
|
||||
int8_t cVFATNeeded = -1, cVFATFoundCur;
|
||||
uint32_t wIndexPos = 0;
|
||||
uint8_t cbFilename;
|
||||
char *Filename = (char *)dname;
|
||||
|
@ -1570,6 +1590,9 @@ bool SdBaseFile::openParent(SdBaseFile* dir) {
|
|||
bool SdBaseFile::openRoot(SdVolume* vol) {
|
||||
// error if file is already open
|
||||
if (isOpen()) {
|
||||
#if defined(DEBUG_SD_ERROR)
|
||||
Com::printErrorFLN(PSTR("Root already open"));
|
||||
#endif
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
|
@ -1587,6 +1610,10 @@ bool SdBaseFile::openRoot(SdVolume* vol) {
|
|||
}
|
||||
} else {
|
||||
// volume is not initialized, invalid, or FAT12 without support
|
||||
#if defined(DEBUG_SD_ERROR)
|
||||
Com::printErrorF(PSTR("volume is not initialized, invalid, or FAT12 without support, type:"));
|
||||
Com::print((int)vol->fatType());Com::println();
|
||||
#endif
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
|
@ -1603,6 +1630,9 @@ bool SdBaseFile::openRoot(SdVolume* vol) {
|
|||
return true;
|
||||
|
||||
fail:
|
||||
#if defined(DEBUG_SD_ERROR)
|
||||
Com::printErrorFLN(PSTR("SD open root dir failed"));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -2055,7 +2085,7 @@ dir_t *SdBaseFile::getLongFilename(dir_t *dir, char *longFilename, int8_t cVFATN
|
|||
|
||||
bool SdBaseFile::findSpace(dir_t *dir, int8_t cVFATNeeded, int8_t *pcVFATFound, uint32_t *pwIndexPos)
|
||||
{
|
||||
int16_t n;
|
||||
//int16_t n; // unused
|
||||
int8_t cVFATFound = 0;
|
||||
// if not a directory file or miss-positioned return an error
|
||||
if (!isDir()) return -1;
|
||||
|
@ -2081,7 +2111,7 @@ bool SdBaseFile::findSpace(dir_t *dir, int8_t cVFATNeeded, int8_t *pcVFATFound,
|
|||
{
|
||||
if (DIR_IS_LONG_NAME(dir))
|
||||
{
|
||||
vfat_t *VFAT = (vfat_t*)dir;
|
||||
//vfat_t *VFAT = (vfat_t*)dir; // unused
|
||||
cVFATFound++;
|
||||
}
|
||||
else
|
||||
|
@ -3029,7 +3059,10 @@ void (*SdBaseFile::oldDateTime_)(uint16_t& date, uint16_t& time) = 0; // NOLINT
|
|||
* initialize SPI pins
|
||||
*/
|
||||
static void spiBegin() {
|
||||
// Already spi init for EEPROM in Alligator boards
|
||||
#if !defined(EEPROM_AVAILABLE) || !defined(EEPROM_SPI_ALLIGATOR) || EEPROM_AVAILABLE != EEPROM_SPI_ALLIGATOR
|
||||
HAL::spiBegin();
|
||||
#endif
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
|
@ -3199,7 +3232,7 @@ uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) {
|
|||
|
||||
#if USE_SD_CRC
|
||||
// form message
|
||||
uint8_t d[6] = {cmd | 0X40, pa[3], pa[2], pa[1], pa[0]};
|
||||
uint8_t d[6] = {static_cast<uint8_t>(cmd | static_cast<uint8_t>(0X40)), pa[3], pa[2], pa[1], pa[0]};
|
||||
|
||||
// add crc
|
||||
d[5] = CRC7(d, 5);
|
||||
|
@ -3395,7 +3428,7 @@ bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
|
|||
if ((spiRec() & 0XC0) == 0XC0) type(SD_CARD_TYPE_SDHC);
|
||||
// discard rest of ocr - contains allowed voltage range
|
||||
for (uint8_t i = 0; i < 3; i++) spiRec();
|
||||
}
|
||||
}
|
||||
#if USE_SD_CRC
|
||||
if (cardCommand(CMD59, 1) > 1) {
|
||||
error(SD_CARD_ERROR_CMD59);
|
||||
|
@ -3412,6 +3445,9 @@ bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
|
|||
|
||||
fail:
|
||||
chipSelectHigh();
|
||||
#if defined(DEBUG_SD_ERROR)
|
||||
Com::printErrorFLN(PSTR("SD card initalization failed"));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -3466,7 +3502,7 @@ bool Sd2Card::readData(uint8_t* dst, size_t count) {
|
|||
goto fail;
|
||||
}
|
||||
// transfer data
|
||||
if (status_ = spiRec(dst, count)) {
|
||||
if ((status_ = spiRec(dst, count))) {
|
||||
error(SD_CARD_ERROR_SPI_DMA);
|
||||
goto fail;
|
||||
}
|
||||
|
@ -4221,7 +4257,7 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
|
|||
cacheStatus_ = 0; // cacheSync() will write block if true
|
||||
cacheBlockNumber_ = 0XFFFFFFFF;
|
||||
cacheFatOffset_ = 0;
|
||||
#if USE_SERARATEFAT_CACHE
|
||||
#if defined(USE_SERARATEFAT_CACHE) && USE_SERARATEFAT_CACHE
|
||||
cacheFatStatus_ = 0; // cacheSync() will write block if true
|
||||
cacheFatBlockNumber_ = 0XFFFFFFFF;
|
||||
#endif // USE_SERARATEFAT_CACHE
|
||||
|
@ -4229,11 +4265,17 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
|
|||
// if part > 0 assume mbr volume with partition table
|
||||
if (part) {
|
||||
if (part > 4) {
|
||||
#if defined(DEBUG_SD_ERROR)
|
||||
Com::printErrorFLN(PSTR("volume init: illegal part"));
|
||||
#endif
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
pc = cacheFetch(volumeStartBlock, CACHE_FOR_READ);
|
||||
if (!pc) {
|
||||
#if defined(DEBUG_SD_ERROR)
|
||||
Com::printErrorFLN(PSTR("volume init: cache fetch failed"));
|
||||
#endif
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
|
@ -4242,6 +4284,9 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
|
|||
p->totalSectors < 100 ||
|
||||
p->firstSector == 0) {
|
||||
// not a valid partition
|
||||
#if defined(DEBUG_SD_ERROR)
|
||||
Com::printErrorFLN(PSTR("volume init: invalid partition"));
|
||||
#endif
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
|
@ -4249,6 +4294,9 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
|
|||
}
|
||||
pc = cacheFetch(volumeStartBlock, CACHE_FOR_READ);
|
||||
if (!pc) {
|
||||
#if defined(DEBUG_SD_ERROR)
|
||||
Com::printErrorFLN(PSTR("volume init: cache fetch failed"));
|
||||
#endif
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
|
@ -4258,6 +4306,13 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
|
|||
fbs->reservedSectorCount == 0 ||
|
||||
fbs->sectorsPerCluster == 0) {
|
||||
// not valid FAT volume
|
||||
#if defined(DEBUG_SD_ERROR)
|
||||
Com::printErrorFLN(PSTR("volume init: not a valid FAT volume"));
|
||||
Com::printFLN(PSTR("BytesPerSector:"),fbs->bytesPerSector);
|
||||
Com::printFLN(PSTR("fatCount:"),fbs->fatCount);
|
||||
Com::printFLN(PSTR("reservedSectorCount:"),fbs->reservedSectorCount);
|
||||
Com::printFLN(PSTR("sectorsPerCluster:"),fbs->sectorsPerCluster);
|
||||
#endif
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
|
@ -4300,6 +4355,9 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
|
|||
if (clusterCount_ < 4085) {
|
||||
fatType_ = 12;
|
||||
if (!FAT12_SUPPORT) {
|
||||
#if defined(DEBUG_SD_ERROR)
|
||||
Com::printErrorFLN(PSTR("volume init: No FAT 12 support"));
|
||||
#endif
|
||||
DBG_FAIL_MACRO;
|
||||
goto fail;
|
||||
}
|
||||
|
@ -4312,6 +4370,9 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
|
|||
return true;
|
||||
|
||||
fail:
|
||||
#if defined(DEBUG_SD_ERROR)
|
||||
Com::printErrorFLN(PSTR("SD volume open failed"));
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
// =============== SdFile.cpp ====================
|
||||
|
|
|
@ -1937,7 +1937,7 @@ class SdBaseFile {
|
|||
uint8_t lfn_checksum(const unsigned char *pFCBName);
|
||||
bool openParentReturnFile(SdBaseFile* dirFile, const char* path, uint8_t *dname, SdBaseFile *newParent, boolean bMakeDirs);
|
||||
|
||||
|
||||
|
||||
/** \return True if this is a directory else false. */
|
||||
bool isDir() const {return type_ >= FAT_FILE_TYPE_MIN_DIR;}
|
||||
/** \return True if this is a normal file else false. */
|
||||
|
@ -2057,7 +2057,7 @@ class SdBaseFile {
|
|||
dir_t* readDirCacheSpecial();
|
||||
dir_t *getLongFilename(dir_t *dir, char *longFilename, int8_t cVFATNeeded, uint32_t *pwIndexPos);
|
||||
bool findSpace(dir_t *dir, int8_t cVFATNeeded, int8_t *pcVFATFound, uint32_t *pwIndexPos);
|
||||
uint8_t lsRecursive(SdBaseFile *parent, uint8_t level, char *findFilename, SdBaseFile *pParentFound);
|
||||
uint8_t lsRecursive(SdBaseFile *parent, uint8_t level, char *findFilename, SdBaseFile *pParentFound, bool isJson);
|
||||
|
||||
bool setDirSize();
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -2208,6 +2208,9 @@ class SdBaseFile {
|
|||
static bool remove(SdBaseFile& dirFile, const char* path) // NOLINT
|
||||
__attribute__((error("use remove(&dirFile, path)")));
|
||||
#endif // ALLOW_DEPRECATED_FUNCTIONS
|
||||
#if JSON_OUTPUT
|
||||
void lsJSON();
|
||||
#endif
|
||||
};
|
||||
//------------------------------------------------------------------------------
|
||||
/**
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -43,6 +43,9 @@ int8_t GCode::waitingForResend = -1; ///< Waiting for line to be resend. -1 =
|
|||
volatile uint8_t GCode::bufferLength = 0; ///< Number of commands stored in gcode_buffer
|
||||
millis_t GCode::timeOfLastDataPacket = 0; ///< Time, when we got the last data packet. Used to detect missing uint8_ts.
|
||||
uint8_t GCode::formatErrors = 0;
|
||||
PGM_P GCode::fatalErrorMsg = NULL; ///< message unset = no fatal error
|
||||
millis_t GCode::lastBusySignal = 0; ///< When was the last busy signal
|
||||
uint32_t GCode::keepAliveInterval = KEEP_ALIVE_INTERVAL;
|
||||
|
||||
/** \page Repetier-protocol
|
||||
|
||||
|
@ -149,6 +152,23 @@ uint8_t GCode::computeBinarySize(char *ptr) // unsigned int bitfield) {
|
|||
return s;
|
||||
}
|
||||
|
||||
void GCode::keepAlive(enum FirmwareState state) {
|
||||
millis_t now = HAL::timeInMilliseconds();
|
||||
|
||||
if(state != NotBusy && keepAliveInterval != 0) {
|
||||
if(now - lastBusySignal < keepAliveInterval)
|
||||
return;
|
||||
if(state == Paused) {
|
||||
Com::printFLN(PSTR("busy:paused for user interaction"));
|
||||
} else if(state == WaitHeater) {
|
||||
Com::printFLN(PSTR("busy:heating"));
|
||||
} else { // processing and uncaught cases
|
||||
Com::printFLN(PSTR("busy:processing"));
|
||||
}
|
||||
}
|
||||
lastBusySignal = now;
|
||||
}
|
||||
|
||||
void GCode::requestResend()
|
||||
{
|
||||
HAL::serialFlush();
|
||||
|
@ -186,6 +206,8 @@ void GCode::checkAndPushCommand()
|
|||
{
|
||||
lastLineNumber++;
|
||||
return;
|
||||
} else if(M == 668) {
|
||||
lastLineNumber = 0; // simulate a reset so lines are out of resend buffer
|
||||
}
|
||||
#endif // DEBUG_COM_ERRORS
|
||||
}
|
||||
|
@ -219,14 +241,32 @@ void GCode::checkAndPushCommand()
|
|||
return;
|
||||
}
|
||||
lastLineNumber = actLineNumber;
|
||||
}
|
||||
pushCommand();
|
||||
} /*
|
||||
This test is not compatible with all hosts. Replaced by forbidding backward switch of protocols.
|
||||
else if(lastLineNumber && !(hasM() && M == 117)) { // once line number always line number!
|
||||
if(Printer::debugErrors())
|
||||
{
|
||||
Com::printErrorFLN(PSTR("Missing linenumber"));
|
||||
}
|
||||
requestResend();
|
||||
return;
|
||||
}*/
|
||||
if(GCode::hasFatalError() && !(hasM() && M==999)) {
|
||||
GCode::reportFatalError();
|
||||
} else {
|
||||
pushCommand();
|
||||
}
|
||||
#ifdef DEBUG_COM_ERRORS
|
||||
if(hasM() && M == 667)
|
||||
return; // omit ok
|
||||
#endif
|
||||
#if ACK_WITH_LINENUMBER
|
||||
Com::printFLN(Com::tOkSpace, actLineNumber);
|
||||
#else
|
||||
Com::printFLN(Com::tOk);
|
||||
#endif
|
||||
wasLastCommandReceivedAsBinary = sendAsBinary;
|
||||
keepAlive(NotBusy);
|
||||
waitingForResend = -1; // everything is ok.
|
||||
}
|
||||
|
||||
|
@ -305,8 +345,10 @@ void GCode::executeFString(FSTRINGPARAM(cmd))
|
|||
buf[buflen++] = c;
|
||||
}
|
||||
while(buflen < 79);
|
||||
if(buflen == 0) // empty line ignore
|
||||
if(buflen == 0) { // empty line ignore
|
||||
if(!c) return; // Special case \n0
|
||||
continue;
|
||||
}
|
||||
buf[buflen] = 0;
|
||||
// Send command into command buffer
|
||||
if(code.parseAscii((char *)buf,false) && (code.params & 518)) // Success
|
||||
|
@ -329,14 +371,17 @@ It must be called frequently to empty the incoming buffer.
|
|||
*/
|
||||
void GCode::readFromSerial()
|
||||
{
|
||||
if(bufferLength >= GCODE_BUFFER_SIZE) return; // all buffers full
|
||||
if(waitUntilAllCommandsAreParsed && bufferLength) return;
|
||||
if(bufferLength >= GCODE_BUFFER_SIZE || (waitUntilAllCommandsAreParsed && bufferLength)) {
|
||||
keepAlive(Processing);
|
||||
return; // all buffers full
|
||||
}
|
||||
waitUntilAllCommandsAreParsed = false;
|
||||
millis_t time = HAL::timeInMilliseconds();
|
||||
if(!HAL::serialByteAvailable())
|
||||
{
|
||||
if((waitingForResend >= 0 || commandsReceivingWritePosition > 0) && time - timeOfLastDataPacket > 200)
|
||||
{
|
||||
// Com::printF(PSTR("WFR:"),waitingForResend);Com::printF(PSTR(" CRWP:"),commandsReceivingWritePosition);commandReceiving[commandsReceivingWritePosition] = 0;Com::printFLN(PSTR(" GOT:"),(char*)commandReceiving);
|
||||
requestResend(); // Something is wrong, a started line was not continued in the last second
|
||||
timeOfLastDataPacket = time;
|
||||
}
|
||||
|
@ -387,13 +432,15 @@ void GCode::readFromSerial()
|
|||
return;
|
||||
}
|
||||
}
|
||||
else // Ascii command
|
||||
else // ASCII command
|
||||
{
|
||||
char ch = commandReceiving[commandsReceivingWritePosition - 1];
|
||||
if(ch == 0 || ch == '\n' || ch == '\r' || (!commentDetected && ch == ':')) // complete line read
|
||||
if(ch == 0 || ch == '\n' || ch == '\r' /*|| (!commentDetected && ch == ':')*/) // complete line read
|
||||
{
|
||||
//Com::printF(PSTR("Parse ascii"));Com::print((char*)commandReceiving);Com::println();
|
||||
commandReceiving[commandsReceivingWritePosition - 1] = 0;
|
||||
#ifdef DEBUG_ECHO_ASCII
|
||||
Com::printF(PSTR("Got:"));Com::print((char*)commandReceiving);Com::println();
|
||||
#endif
|
||||
commentDetected = false;
|
||||
if(commandsReceivingWritePosition == 1) // empty line ignore
|
||||
{
|
||||
|
@ -410,7 +457,7 @@ void GCode::readFromSerial()
|
|||
}
|
||||
else
|
||||
{
|
||||
if(ch == ';') commentDetected = true; // ignore new data until lineend
|
||||
if(ch == ';') commentDetected = true; // ignore new data until line end
|
||||
if(commentDetected) commandsReceivingWritePosition--;
|
||||
}
|
||||
}
|
||||
|
@ -421,7 +468,7 @@ void GCode::readFromSerial()
|
|||
}
|
||||
}
|
||||
#if SDSUPPORT
|
||||
if(sd.sdmode == 0 || commandsReceivingWritePosition != 0) // not reading or incoming serial command
|
||||
if(sd.sdmode == 0 || sd.sdmode >= 100 || commandsReceivingWritePosition != 0) // not reading or incoming serial command
|
||||
return;
|
||||
while( sd.filesize > sd.sdpos && commandsReceivingWritePosition < MAX_CMD_SIZE) // consume data until no data or buffer full
|
||||
{
|
||||
|
@ -493,7 +540,7 @@ void GCode::readFromSerial()
|
|||
}
|
||||
else
|
||||
{
|
||||
if(ch == ';') commentDetected = true; // ignore new data until lineend
|
||||
if(ch == ';') commentDetected = true; // ignore new data until line end
|
||||
if(commentDetected) commandsReceivingWritePosition--;
|
||||
}
|
||||
}
|
||||
|
@ -513,7 +560,7 @@ void GCode::readFromSerial()
|
|||
bool GCode::parseBinary(uint8_t *buffer,bool fromSerial)
|
||||
{
|
||||
internalCommand = !fromSerial;
|
||||
unsigned int sum1 = 0,sum2 = 0; // for fletcher-16 checksum
|
||||
unsigned int sum1 = 0, sum2 = 0; // for fletcher-16 checksum
|
||||
// first do fletcher-16 checksum tests see
|
||||
// http://en.wikipedia.org/wiki/Fletcher's_checksum
|
||||
uint8_t *p = buffer;
|
||||
|
@ -542,13 +589,13 @@ bool GCode::parseBinary(uint8_t *buffer,bool fromSerial)
|
|||
return false;
|
||||
}
|
||||
p = buffer;
|
||||
params = *(unsigned int *)p;
|
||||
params = *(uint16_t *)p;
|
||||
p += 2;
|
||||
uint8_t textlen = 16;
|
||||
if(isV2())
|
||||
{
|
||||
params2 = *(unsigned int *)p;
|
||||
p+=2;
|
||||
params2 = *(uint16_t *)p;
|
||||
p += 2;
|
||||
if(hasString())
|
||||
textlen = *p++;
|
||||
}
|
||||
|
@ -556,16 +603,16 @@ bool GCode::parseBinary(uint8_t *buffer,bool fromSerial)
|
|||
if(params & 1)
|
||||
{
|
||||
actLineNumber = N = *(uint16_t *)p;
|
||||
p+=2;
|
||||
p += 2;
|
||||
}
|
||||
if(isV2()) // Read G,M as 16 bit value
|
||||
{
|
||||
if(params & 2)
|
||||
if(hasM())
|
||||
{
|
||||
M = *(uint16_t *)p;
|
||||
p += 2;
|
||||
}
|
||||
if(params & 4)
|
||||
if(hasG())
|
||||
{
|
||||
G = *(uint16_t *)p;
|
||||
p += 2;
|
||||
|
@ -573,51 +620,51 @@ bool GCode::parseBinary(uint8_t *buffer,bool fromSerial)
|
|||
}
|
||||
else
|
||||
{
|
||||
if(params & 2)
|
||||
if(hasM())
|
||||
{
|
||||
M = *p++;
|
||||
}
|
||||
if(params & 4)
|
||||
if(hasG())
|
||||
{
|
||||
G = *p++;
|
||||
}
|
||||
}
|
||||
//if(code->params & 8) {memcpy(&code->X,p,4);p+=4;}
|
||||
if(params & 8)
|
||||
if(hasX())
|
||||
{
|
||||
X = *(float *)p;
|
||||
p += 4;
|
||||
}
|
||||
if(params & 16)
|
||||
if(hasY())
|
||||
{
|
||||
Y = *(float *)p;
|
||||
p += 4;
|
||||
}
|
||||
if(params & 32)
|
||||
if(hasZ())
|
||||
{
|
||||
Z = *(float *)p;
|
||||
p += 4;
|
||||
}
|
||||
if(params & 64)
|
||||
if(hasE())
|
||||
{
|
||||
E = *(float *)p;
|
||||
p += 4;
|
||||
}
|
||||
if(params & 256)
|
||||
if(hasF())
|
||||
{
|
||||
F = *(float *)p;
|
||||
p += 4;
|
||||
}
|
||||
if(params & 512)
|
||||
if(hasT())
|
||||
{
|
||||
T = *p++;
|
||||
}
|
||||
if(params & 1024)
|
||||
if(hasS())
|
||||
{
|
||||
S = *(int32_t*)p;
|
||||
p += 4;
|
||||
}
|
||||
if(params & 2048)
|
||||
if(hasP())
|
||||
{
|
||||
P = *(int32_t*)p;
|
||||
p += 4;
|
||||
|
@ -681,14 +728,14 @@ bool GCode::parseBinary(uint8_t *buffer,bool fromSerial)
|
|||
{
|
||||
text = (char*)p;
|
||||
text[textlen] = 0; // Terminate string overwriting checksum
|
||||
waitUntilAllCommandsAreParsed=true; // Don't destroy string until executed
|
||||
waitUntilAllCommandsAreParsed = true; // Don't destroy string until executed
|
||||
}
|
||||
formatErrors = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
Converts a ascii GCode line into a GCode structure.
|
||||
Converts a ASCII GCode line into a GCode structure.
|
||||
*/
|
||||
bool GCode::parseAscii(char *line,bool fromSerial)
|
||||
{
|
||||
|
@ -696,9 +743,11 @@ bool GCode::parseAscii(char *line,bool fromSerial)
|
|||
params = 0;
|
||||
params2 = 0;
|
||||
internalCommand = !fromSerial;
|
||||
bool hasChecksum = false;
|
||||
char c;
|
||||
while ( (c = *(pos++)) )
|
||||
{
|
||||
if(c == '(' || c == '%') break; // alternative comment or program block
|
||||
switch(c)
|
||||
{
|
||||
case 'N':
|
||||
|
@ -721,10 +770,10 @@ bool GCode::parseAscii(char *line,bool fromSerial)
|
|||
case 'm':
|
||||
{
|
||||
M = parseLongValue(pos) & 0xffff;
|
||||
params |=2;
|
||||
params |= 2;
|
||||
if(M > 255) params |= 4096;
|
||||
// handle non standard text arguments that some M codes have
|
||||
if (M == 23 || M == 28 || M == 29 || M == 30 || M == 32 || M == 117)
|
||||
if (M == 20 || M == 23 || M == 28 || M == 29 || M == 30 || M == 32 || M == 36 || M == 117)
|
||||
{
|
||||
// after M command we got a filename or text
|
||||
char digit;
|
||||
|
@ -737,15 +786,15 @@ bool GCode::parseAscii(char *line,bool fromSerial)
|
|||
{
|
||||
if (digit != ' ') break;
|
||||
pos++;
|
||||
// skip leading whitespaces (may be no white space)
|
||||
// skip leading white spaces (may be no white space)
|
||||
}
|
||||
text = pos;
|
||||
while (*pos)
|
||||
{
|
||||
if((M != 117 && *pos==' ') || *pos=='*') break;
|
||||
if((M != 117 && M != 20 && *pos==' ') || *pos=='*') break;
|
||||
pos++; // find a space as file name end
|
||||
}
|
||||
*pos = 0; // truncate filename by erasing space with nul, also skips checksum
|
||||
*pos = 0; // truncate filename by erasing space with null, also skips checksum
|
||||
waitUntilAllCommandsAreParsed = true; // don't risk string be deleted
|
||||
params |= 32768;
|
||||
}
|
||||
|
@ -839,11 +888,67 @@ bool GCode::parseAscii(char *line,bool fromSerial)
|
|||
params |= 4096; // Needs V2 for saving
|
||||
break;
|
||||
}
|
||||
case 'C':
|
||||
case 'c':
|
||||
{
|
||||
C = parseFloatValue(pos);
|
||||
params2 |= 16;
|
||||
params |= 4096; // Needs V2 for saving
|
||||
break;
|
||||
}
|
||||
case 'H':
|
||||
case 'h':
|
||||
{
|
||||
H = parseFloatValue(pos);
|
||||
params2 |= 32;
|
||||
params |= 4096; // Needs V2 for saving
|
||||
break;
|
||||
}
|
||||
case 'A':
|
||||
case 'a':
|
||||
{
|
||||
A = parseFloatValue(pos);
|
||||
params2 |= 64;
|
||||
params |= 4096; // Needs V2 for saving
|
||||
break;
|
||||
}
|
||||
case 'B':
|
||||
case 'b':
|
||||
{
|
||||
B = parseFloatValue(pos);
|
||||
params2 |= 128;
|
||||
params |= 4096; // Needs V2 for saving
|
||||
break;
|
||||
}
|
||||
case 'K':
|
||||
case 'k':
|
||||
{
|
||||
K = parseFloatValue(pos);
|
||||
params2 |= 256;
|
||||
params |= 4096; // Needs V2 for saving
|
||||
break;
|
||||
}
|
||||
case 'L':
|
||||
case 'l':
|
||||
{
|
||||
L = parseFloatValue(pos);
|
||||
params2 |= 512;
|
||||
params |= 4096; // Needs V2 for saving
|
||||
break;
|
||||
}
|
||||
case 'O':
|
||||
case 'o':
|
||||
{
|
||||
O = parseFloatValue(pos);
|
||||
params2 |= 1024;
|
||||
params |= 4096; // Needs V2 for saving
|
||||
break;
|
||||
}
|
||||
case '*' : //checksum
|
||||
{
|
||||
uint8_t checksum_given = parseLongValue(pos);
|
||||
uint8_t checksum = 0;
|
||||
while(line != (pos-1)) checksum ^= *line++;
|
||||
while(line != (pos - 1)) checksum ^= *line++;
|
||||
#if FEATURE_CHECKSUM_FORCED
|
||||
Printer::flag0 |= PRINTER_FLAG0_FORCE_CHECKSUM;
|
||||
#endif
|
||||
|
@ -855,19 +960,23 @@ bool GCode::parseAscii(char *line,bool fromSerial)
|
|||
}
|
||||
return false; // mismatch
|
||||
}
|
||||
hasChecksum = true;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}// end switch
|
||||
}// end while
|
||||
|
||||
if(hasFormatError() || (params & 518)==0) // Must contain G, M or T command and parameter need to have variables!
|
||||
if(wasLastCommandReceivedAsBinary && !hasChecksum && fromSerial && !waitUntilAllCommandsAreParsed) {
|
||||
Com::printErrorFLN("Checksum required when switching back to ASCII protocol.");
|
||||
return false;
|
||||
}
|
||||
if(hasFormatError() /*|| (params & 518) == 0*/) // Must contain G, M or T command and parameter need to have variables!
|
||||
{
|
||||
formatErrors++;
|
||||
if(Printer::debugErrors())
|
||||
Com::printErrorFLN(Com::tFormatError);
|
||||
if(formatErrors<3) return false;
|
||||
if(formatErrors < 3) return false;
|
||||
}
|
||||
else formatErrors = 0;
|
||||
return true;
|
||||
|
@ -878,7 +987,7 @@ void GCode::printCommand()
|
|||
{
|
||||
if(hasN()) {
|
||||
Com::print('N');
|
||||
Com::print((long)N);
|
||||
Com::print((int32_t)N);
|
||||
Com::print(' ');
|
||||
}
|
||||
if(hasM())
|
||||
|
@ -945,3 +1054,224 @@ void GCode::printCommand()
|
|||
}
|
||||
Com::println();
|
||||
}
|
||||
|
||||
void GCode::fatalError(FSTRINGPARAM(message)) {
|
||||
fatalErrorMsg = message;
|
||||
#if SDSUPPORT
|
||||
if(sd.sdmode != 0) { // stop sd print to prevent damage
|
||||
sd.stopPrint();
|
||||
}
|
||||
#endif
|
||||
if(Printer::currentPosition[Z_AXIS] < Printer::zMin + Printer::zLength - 15)
|
||||
PrintLine::moveRelativeDistanceInSteps(0, 0, 10 * Printer::axisStepsPerMM[Z_AXIS], 0, Printer::homingFeedrate[Z_AXIS], true, true);
|
||||
EVENT_FATAL_ERROR_OCCURED
|
||||
Commands::waitUntilEndOfAllMoves();
|
||||
reportFatalError();
|
||||
Printer::kill(false);
|
||||
}
|
||||
|
||||
void GCode::reportFatalError() {
|
||||
Com::printF(Com::tFatal);
|
||||
Com::printF(fatalErrorMsg);
|
||||
Com::printFLN(PSTR(" Printer stopped and heaters disabled due to this error. Fix error and restart with M999."));
|
||||
UI_ERROR_P(fatalErrorMsg)
|
||||
}
|
||||
|
||||
void GCode::resetFatalError() {
|
||||
TemperatureController::resetAllErrorStates();
|
||||
Printer::debugReset(8); // disable dry run
|
||||
fatalErrorMsg = NULL;
|
||||
UI_ERROR("");
|
||||
EVENT_CONTINUE_FROM_FATAL_ERROR
|
||||
Com::printFLN(PSTR("info:Continue from fatal state"));
|
||||
}
|
||||
|
||||
#if JSON_OUTPUT
|
||||
|
||||
// --------------------------------------------------------------- //
|
||||
// Code that gets gcode information is adapted from RepRapFirmware //
|
||||
// Originally licensed under GPL //
|
||||
// Authors: reprappro, dc42, dcnewman, others //
|
||||
// Source: https://github.com/dcnewman/RepRapFirmware //
|
||||
// Copy date: 15 Nov 2015 //
|
||||
// --------------------------------------------------------------- //
|
||||
|
||||
void GCodeFileInfo::init(SdBaseFile &file) {
|
||||
this->fileSize = file.fileSize();
|
||||
this->filamentNeeded = 0.0;
|
||||
this->objectHeight = 0.0;
|
||||
this->layerHeight = 0.0;
|
||||
if (!file.isOpen()) return;
|
||||
bool genByFound = false, layerHeightFound = false, filamentNeedFound = false;
|
||||
#if CPU_ARCH==ARCH_AVR
|
||||
#define GCI_BUF_SIZE 120
|
||||
#else
|
||||
#define GCI_BUF_SIZE 1024
|
||||
#endif
|
||||
// READ 4KB FROM THE BEGINNING
|
||||
char buf[GCI_BUF_SIZE];
|
||||
for (int i = 0; i < 4096; i += GCI_BUF_SIZE-50) {
|
||||
if(!file.seekSet(i)) break;
|
||||
file.read(buf, GCI_BUF_SIZE);
|
||||
if (!genByFound && findGeneratedBy(buf, this->generatedBy)) genByFound = true;
|
||||
if (!layerHeightFound && findLayerHeight(buf, this->layerHeight)) layerHeightFound = true;
|
||||
if (!filamentNeedFound && findFilamentNeed(buf, this->filamentNeeded)) filamentNeedFound = true;
|
||||
if(genByFound && layerHeightFound && filamentNeedFound) goto get_objectHeight;
|
||||
}
|
||||
|
||||
// READ 4KB FROM END
|
||||
for (int i = 0; i < 4096; i += GCI_BUF_SIZE-50) {
|
||||
if(!file.seekEnd(-4096 + i)) break;
|
||||
file.read(buf, GCI_BUF_SIZE);
|
||||
if (!genByFound && findGeneratedBy(buf, this->generatedBy)) genByFound = true;
|
||||
if (!layerHeightFound && findLayerHeight(buf, this->layerHeight)) layerHeightFound = true;
|
||||
if (!filamentNeedFound && findFilamentNeed(buf, this->filamentNeeded)) filamentNeedFound = true;
|
||||
if(genByFound && layerHeightFound && filamentNeedFound) goto get_objectHeight;
|
||||
}
|
||||
|
||||
get_objectHeight:
|
||||
// MOVE FROM END UP IN 1KB BLOCKS UP TO 30KB
|
||||
for (int i = GCI_BUF_SIZE; i < 30000; i += GCI_BUF_SIZE-50) {
|
||||
if(!file.seekEnd(-i)) break;
|
||||
file.read(buf, GCI_BUF_SIZE);
|
||||
if (findTotalHeight(buf, this->objectHeight)) break;
|
||||
}
|
||||
file.seekSet(0);
|
||||
}
|
||||
|
||||
bool GCodeFileInfo::findGeneratedBy(char *buf, char *genBy) {
|
||||
// Slic3r & S3D
|
||||
const char* generatedByString = PSTR("generated by ");
|
||||
char* pos = strstr_P(buf, generatedByString);
|
||||
if (pos) {
|
||||
pos += strlen_P(generatedByString);
|
||||
size_t i = 0;
|
||||
while (i < GENBY_SIZE - 1 && *pos >= ' ') {
|
||||
char c = *pos++;
|
||||
if (c == '"' || c == '\\') {
|
||||
// Need to escape the quote-mark for JSON
|
||||
if (i > GENBY_SIZE - 3) break;
|
||||
genBy[i++] = '\\';
|
||||
}
|
||||
genBy[i++] = c;
|
||||
}
|
||||
genBy[i] = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
// CURA
|
||||
const char* slicedAtString = PSTR(";Sliced at: ");
|
||||
pos = strstr_P(buf, slicedAtString);
|
||||
if (pos) {
|
||||
strcpy_P(genBy, PSTR("Cura"));
|
||||
return true;
|
||||
}
|
||||
|
||||
// UNKNOWN
|
||||
strcpy_P(genBy, PSTR("Unknown"));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GCodeFileInfo::findLayerHeight(char *buf, float &layerHeight) {
|
||||
// SLIC3R
|
||||
layerHeight = 0;
|
||||
const char* layerHeightSlic3r = PSTR("; layer_height ");
|
||||
char *pos = strstr_P(buf, layerHeightSlic3r);
|
||||
if (pos) {
|
||||
pos += strlen_P(layerHeightSlic3r);
|
||||
while (*pos == ' ' || *pos == 't' || *pos == '=' || *pos == ':') {
|
||||
++pos;
|
||||
}
|
||||
layerHeight = strtod(pos, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
// CURA
|
||||
const char* layerHeightCura = PSTR("Layer height: ");
|
||||
pos = strstr_P(buf, layerHeightCura);
|
||||
if (pos) {
|
||||
pos += strlen_P(layerHeightCura);
|
||||
while (*pos == ' ' || *pos == 't' || *pos == '=' || *pos == ':') {
|
||||
++pos;
|
||||
}
|
||||
layerHeight = strtod(pos, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GCodeFileInfo::findFilamentNeed(char *buf, float &filament) {
|
||||
const char* filamentUsedStr = PSTR("filament used");
|
||||
const char* pos = strstr_P(buf, filamentUsedStr);
|
||||
filament = 0;
|
||||
if (pos != NULL) {
|
||||
pos += strlen_P(filamentUsedStr);
|
||||
while (*pos == ' ' || *pos == 't' || *pos == '=' || *pos == ':') {
|
||||
++pos; // this allows for " = " from default slic3r comment and ": " from default Cura comment
|
||||
}
|
||||
if (isDigit(*pos)) {
|
||||
char *q;
|
||||
filament += strtod(pos, &q);
|
||||
if (*q == 'm' && *(q + 1) != 'm') {
|
||||
filament *= 1000.0; // Cura outputs filament used in metres not mm
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GCodeFileInfo::findTotalHeight(char *buf, float &height) {
|
||||
int len = 1024;
|
||||
bool inComment, inRelativeMode = false;
|
||||
unsigned int zPos;
|
||||
for (int i = len - 5; i > 0; i--) {
|
||||
if (inRelativeMode) {
|
||||
inRelativeMode = !(buf[i] == 'G' && buf[i + 1] == '9' && buf[i + 2] == '1' && buf[i + 3] <= ' ');
|
||||
} else if (buf[i] == 'G') {
|
||||
// Ignore G0/G1 codes if absolute mode was switched back using G90 (typical for Cura files)
|
||||
if (buf[i + 1] == '9' && buf[i + 2] == '0' && buf[i + 3] <= ' ') {
|
||||
inRelativeMode = true;
|
||||
} else if ((buf[i + 1] == '0' || buf[i + 1] == '1') && buf[i + 2] == ' ') {
|
||||
// Look for last "G0/G1 ... Z#HEIGHT#" command as generated by common slicers
|
||||
// Looks like we found a controlled move, however it could be in a comment, especially when using slic3r 1.1.1
|
||||
inComment = false;
|
||||
size_t j = i;
|
||||
while (j != 0) {
|
||||
--j;
|
||||
char c = buf[j];
|
||||
if (c == '\n' || c == '\r') break;
|
||||
if (c == ';') {
|
||||
// It is in a comment, so give up on this one
|
||||
inComment = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (inComment) continue;
|
||||
|
||||
// Find 'Z' position and grab that value
|
||||
zPos = 0;
|
||||
for (int j = i + 3; j < len - 2; j++) {
|
||||
char c = buf[j];
|
||||
if (c < ' ') {
|
||||
// Skip all whitespaces...
|
||||
while (j < len - 2 && c <= ' ') {
|
||||
c = buf[++j];
|
||||
}
|
||||
// ...to make sure ";End" doesn't follow G0 .. Z#HEIGHT#
|
||||
if (zPos != 0) {
|
||||
//debugPrintf("Found at offset %u text: %.100s\n", zPos, &buf[zPos + 1]);
|
||||
height = strtod(&buf[zPos + 1], NULL);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
} else if (c == ';') break;
|
||||
else if (c == 'Z') zPos = j;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif // JSON_OUTPUT
|
||||
|
|
|
@ -19,22 +19,26 @@
|
|||
#define _GCODE_H
|
||||
|
||||
#define MAX_CMD_SIZE 96
|
||||
#define ARRAY_SIZE(_x) (sizeof(_x)/sizeof(_x[0]))
|
||||
|
||||
enum FirmwareState {NotBusy=0,Processing,Paused,WaitHeater};
|
||||
|
||||
class SDCard;
|
||||
class GCode // 52 uint8_ts per command needed
|
||||
{
|
||||
unsigned int params;
|
||||
unsigned int params2;
|
||||
uint16_t params;
|
||||
uint16_t params2;
|
||||
public:
|
||||
unsigned int N; // Line number
|
||||
unsigned int M;
|
||||
unsigned int G;
|
||||
uint16_t N; // Line number
|
||||
uint16_t M;
|
||||
uint16_t G;
|
||||
float X;
|
||||
float Y;
|
||||
float Z;
|
||||
float E;
|
||||
float F;
|
||||
long S;
|
||||
long P;
|
||||
int32_t S;
|
||||
int32_t P;
|
||||
float I;
|
||||
float J;
|
||||
float R;
|
||||
|
@ -71,14 +75,23 @@ public:
|
|||
{
|
||||
return ((params & 8)!=0);
|
||||
}
|
||||
inline void unsetX() {
|
||||
params &= ~8;
|
||||
}
|
||||
inline bool hasY()
|
||||
{
|
||||
return ((params & 16)!=0);
|
||||
}
|
||||
inline void unsetY() {
|
||||
params &= ~16;
|
||||
}
|
||||
inline bool hasZ()
|
||||
{
|
||||
return ((params & 32)!=0);
|
||||
}
|
||||
inline void unsetZ() {
|
||||
params &= ~32;
|
||||
}
|
||||
inline bool hasNoXYZ()
|
||||
{
|
||||
return ((params & 56)==0);
|
||||
|
@ -181,9 +194,17 @@ public:
|
|||
static void pushCommand();
|
||||
static void executeFString(FSTRINGPARAM(cmd));
|
||||
static uint8_t computeBinarySize(char *ptr);
|
||||
|
||||
static void fatalError(FSTRINGPARAM(message));
|
||||
static void reportFatalError();
|
||||
static void resetFatalError();
|
||||
inline static bool hasFatalError() {
|
||||
return fatalErrorMsg != NULL;
|
||||
}
|
||||
static void keepAlive(enum FirmwareState state);
|
||||
static uint32_t keepAliveInterval;
|
||||
friend class SDCard;
|
||||
friend class UIDisplay;
|
||||
static FSTRINGPARAM(fatalErrorMsg);
|
||||
private:
|
||||
void debugCommandBuffer();
|
||||
void checkAndPushCommand();
|
||||
|
@ -191,6 +212,7 @@ private:
|
|||
inline float parseFloatValue(char *s)
|
||||
{
|
||||
char *endPtr;
|
||||
while(*s == 32) s++; // skip spaces
|
||||
float f = (strtod(s, &endPtr));
|
||||
if(s == endPtr) f=0.0; // treat empty string "x " as "x0"
|
||||
return f;
|
||||
|
@ -198,6 +220,7 @@ private:
|
|||
inline long parseLongValue(char *s)
|
||||
{
|
||||
char *endPtr;
|
||||
while(*s == 32) s++; // skip spaces
|
||||
long l = (strtol(s, &endPtr, 10));
|
||||
if(s == endPtr) l=0; // treat empty string argument "p " as "p0"
|
||||
return l;
|
||||
|
@ -219,8 +242,29 @@ private:
|
|||
static volatile uint8_t bufferLength; ///< Number of commands stored in gcode_buffer
|
||||
static millis_t timeOfLastDataPacket; ///< Time, when we got the last data packet. Used to detect missing uint8_ts.
|
||||
static uint8_t formatErrors; ///< Number of sequential format errors
|
||||
static millis_t lastBusySignal; ///< When was the last busy signal
|
||||
};
|
||||
|
||||
#if JSON_OUTPUT
|
||||
#include "SdFat.h"
|
||||
// Struct to hold Gcode file information 32 bytes
|
||||
#define GENBY_SIZE 16
|
||||
class GCodeFileInfo {
|
||||
public:
|
||||
void init(SdBaseFile &file);
|
||||
|
||||
unsigned long fileSize;
|
||||
float objectHeight;
|
||||
float layerHeight;
|
||||
float filamentNeeded;
|
||||
char generatedBy[GENBY_SIZE];
|
||||
|
||||
bool findGeneratedBy(char *buf, char *genBy);
|
||||
bool findLayerHeight(char *buf, float &layerHeight);
|
||||
bool findFilamentNeed(char *buf, float &filament);
|
||||
bool findTotalHeight(char *buf, float &objectHeight);
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
// http://en.radzio.dxp.pl/bitmap_converter/
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#ifndef CUSTOM_LOGO
|
||||
#define LOGO_WIDTH 60
|
||||
#define LOGO_HEIGHT 64
|
||||
|
||||
|
@ -39,39 +40,7 @@ const unsigned char logo[] PROGMEM = { //AVR-GCC, WinAVR
|
|||
0x00, 0x07, 0xFF, 0xFF, 0xF8, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFC, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x03, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0xF8, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
/*
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xDF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F,
|
||||
0xFF, 0xFF, 0xF7, 0x83, 0xC1, 0xF0, 0x1E, 0x0F, 0xFF, 0xFF, 0x7C, 0x0F, 0x07, 0xC0, 0x78, 0x0F,
|
||||
0xFF, 0xFD, 0xE0, 0x00, 0x00, 0x01, 0xE0, 0x3F, 0xFF, 0xDF, 0x80, 0x00, 0x00, 0x07, 0xC0, 0x7F,
|
||||
0xFE, 0x3F, 0xFF, 0xFF, 0xFF, 0xDF, 0x01, 0xFF, 0xF8, 0x00, 0x00, 0x0B, 0xFF, 0xFC, 0x03, 0xFF,
|
||||
0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF,
|
||||
0xF0, 0x50, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xF1, 0xFF, 0xFF, 0xFF, 0xD0, 0x00, 0x7F, 0x7F,
|
||||
0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x7E, 0x7F, 0xF3, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xFC, 0x7F,
|
||||
0xF9, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF8, 0x3F, 0xF1, 0xEF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0x3F,
|
||||
0xF9, 0xE0, 0x00, 0x0F, 0xFF, 0xF0, 0xE0, 0x3F, 0xF1, 0xE0, 0x00, 0x00, 0xFF, 0xF8, 0xE0, 0x3F,
|
||||
0xF9, 0xE0, 0x00, 0x00, 0x3F, 0xF0, 0xE3, 0x3F, 0xF1, 0xE0, 0x00, 0x00, 0x1F, 0xF8, 0xE3, 0x7F,
|
||||
0xF9, 0xE0, 0x00, 0x00, 0x0F, 0xF0, 0xE7, 0x3F, 0xF1, 0xE0, 0x00, 0x00, 0x0F, 0xF8, 0xE7, 0x7F,
|
||||
0xF9, 0xE0, 0x08, 0x00, 0x0F, 0xF0, 0xE7, 0x7F, 0xF1, 0xE0, 0x0F, 0xE0, 0x07, 0xF8, 0xE7, 0x7F,
|
||||
0xF9, 0xE0, 0x0F, 0xE0, 0x07, 0xF0, 0xE7, 0x7F, 0xF1, 0xE0, 0x0F, 0xF0, 0x07, 0xF8, 0xE6, 0x7F,
|
||||
0xF9, 0xE0, 0x0F, 0xF0, 0x07, 0xF0, 0xE0, 0x7F, 0xF9, 0xE0, 0x0F, 0xF0, 0x07, 0xF8, 0xE0, 0xFF,
|
||||
0xF9, 0xE0, 0x0F, 0xE0, 0x07, 0xF0, 0xE0, 0xFF, 0xF9, 0xE0, 0x00, 0x00, 0x07, 0xF8, 0xE1, 0xFF,
|
||||
0xF9, 0xE0, 0x00, 0x00, 0x0F, 0xF0, 0xE3, 0xFF, 0xF9, 0xE0, 0x00, 0x00, 0x0F, 0xF8, 0xE3, 0xFF,
|
||||
0xF9, 0xE0, 0x00, 0x00, 0x1F, 0xF8, 0xE7, 0xFF, 0xF9, 0xE0, 0x00, 0x00, 0x3F, 0xF8, 0xE7, 0xFF,
|
||||
0xF9, 0xE0, 0x00, 0x01, 0xFF, 0xF8, 0xE7, 0xFF, 0xF9, 0xE0, 0x0C, 0x01, 0xFF, 0xF8, 0xE7, 0xFF,
|
||||
0xF9, 0xE0, 0x0E, 0x00, 0x7F, 0xF8, 0xE7, 0xFF, 0xF9, 0xE0, 0x0F, 0x00, 0x7F, 0xF8, 0xE7, 0xFF,
|
||||
0xF9, 0xE0, 0x0F, 0x00, 0x3F, 0xF8, 0xE7, 0xFF, 0xF9, 0xE0, 0x0F, 0x80, 0x1F, 0xF8, 0xE7, 0xFF,
|
||||
0xF9, 0xE0, 0x0F, 0x80, 0x1F, 0xF8, 0xE7, 0xFF, 0xF9, 0xE0, 0x0F, 0xC0, 0x0F, 0xF8, 0xE7, 0xFF,
|
||||
0xF9, 0xE0, 0x0F, 0xC0, 0x0F, 0xF8, 0xE7, 0xFF, 0xF9, 0xE0, 0x0F, 0xE0, 0x07, 0xF8, 0xEF, 0xFF,
|
||||
0xF9, 0xF0, 0x0F, 0xE0, 0x07, 0xF8, 0xEF, 0xFF, 0xF9, 0xE0, 0x0F, 0xF0, 0x03, 0xF8, 0xFF, 0xFF,
|
||||
0xF9, 0xF0, 0x0F, 0xF0, 0x03, 0xF8, 0xFF, 0xFF, 0xF9, 0xFE, 0x0F, 0xF8, 0x03, 0xF8, 0xFF, 0xFF,
|
||||
0xF9, 0xFF, 0xFF, 0xF8, 0x01, 0xF8, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xFF, 0x81, 0xF8, 0xFF, 0xFF,
|
||||
0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xFF, 0xFF, 0xF8, 0xFF, 0xFF,
|
||||
0xF8, 0x00, 0xFF, 0xFF, 0xFF, 0xF8, 0xDF, 0xFF, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF,
|
||||
0xFF, 0x40, 0x00, 0x00, 0xFF, 0xF0, 0x3F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xC0, 0x7F, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x80, 0x00, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0xAF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF
|
||||
*/
|
||||
};
|
||||
|
||||
#else
|
||||
LOGO_BITMAP
|
||||
#endif
|
||||
|
|
Plik diff jest za duży
Load Diff
|
@ -28,10 +28,10 @@
|
|||
#define FLAG_WARMUP 1
|
||||
#define FLAG_NOMINAL 2
|
||||
#define FLAG_DECELERATING 4
|
||||
#define FLAG_ACCELERATION_ENABLED 8
|
||||
#define FLAG_ACCELERATION_ENABLED 8 // unused
|
||||
#define FLAG_CHECK_ENDSTOPS 16
|
||||
#define FLAG_SKIP_ACCELERATING 32
|
||||
#define FLAG_SKIP_DEACCELERATING 64
|
||||
#define FLAG_ALL_E_MOTORS 32 // For mixed extruder move all motors instead of selected motor
|
||||
#define FLAG_SKIP_DEACCELERATING 64 // unused
|
||||
#define FLAG_BLOCKED 128
|
||||
|
||||
/** Are the step parameter computed */
|
||||
|
@ -42,7 +42,7 @@
|
|||
#define FLAG_JOIN_START_FIXED 4
|
||||
/** Start filament retraction at move start */
|
||||
#define FLAG_JOIN_START_RETRACT 8
|
||||
/** Wait for filament pushback, before ending move */
|
||||
/** Wait for filament push back, before ending move */
|
||||
#define FLAG_JOIN_END_RETRACT 16
|
||||
/** Disable retract for this line */
|
||||
#define FLAG_JOIN_NO_RETRACT 32
|
||||
|
@ -53,15 +53,13 @@
|
|||
// Printing related data
|
||||
#if NONLINEAR_SYSTEM
|
||||
// Allow the delta cache to store segments for every line in line cache. Beware this gets big ... fast.
|
||||
// DELTASEGMENTS_PER_PRINTLINE *
|
||||
#define DELTA_CACHE_SIZE (DELTASEGMENTS_PER_PRINTLINE * PRINTLINE_CACHE_SIZE)
|
||||
|
||||
class PrintLine;
|
||||
typedef struct
|
||||
{
|
||||
flag8_t dir; ///< Direction of delta movement.
|
||||
uint16_t deltaSteps[TOWER_ARRAY]; ///< Number of steps in move.
|
||||
inline void checkEndstops(PrintLine *cur,bool checkall);
|
||||
inline bool checkEndstops(PrintLine *cur,bool checkall);
|
||||
inline void setXMoveFinished()
|
||||
{
|
||||
dir &= ~XSTEP;
|
||||
|
@ -136,7 +134,7 @@ typedef struct
|
|||
}
|
||||
inline bool isNoMove()
|
||||
{
|
||||
return (dir & XYZE_STEP)==0;
|
||||
return (dir & XYZE_STEP) == 0;
|
||||
}
|
||||
inline bool isXYZMove()
|
||||
{
|
||||
|
@ -148,37 +146,37 @@ typedef struct
|
|||
}
|
||||
inline void setMoveOfAxis(uint8_t axis)
|
||||
{
|
||||
dir |= XSTEP<<axis;
|
||||
dir |= XSTEP << axis;
|
||||
}
|
||||
inline void setPositiveMoveOfAxis(uint8_t axis)
|
||||
{
|
||||
dir |= X_STEP_DIRPOS<<axis;
|
||||
dir |= X_STEP_DIRPOS << axis;
|
||||
}
|
||||
inline void setPositiveDirectionForAxis(uint8_t axis)
|
||||
{
|
||||
dir |= X_DIRPOS<<axis;
|
||||
dir |= X_DIRPOS << axis;
|
||||
}
|
||||
} DeltaSegment;
|
||||
} NonlinearSegment;
|
||||
extern uint8_t lastMoveID;
|
||||
#endif
|
||||
class UIDisplay;
|
||||
class PrintLine // RAM usage: 24*4+15 = 113 Byte
|
||||
{
|
||||
friend class UIDisplay;
|
||||
#if CPU_ARCH==ARCH_ARM
|
||||
#if CPU_ARCH == ARCH_ARM
|
||||
static volatile bool nlFlag;
|
||||
#endif
|
||||
public:
|
||||
static uint8_t linesPos; // Position for executing line movement
|
||||
static ufast8_t linesPos; // Position for executing line movement
|
||||
static PrintLine lines[];
|
||||
static uint8_t linesWritePos; // Position where we write the next cached line move
|
||||
flag8_t joinFlags;
|
||||
volatile flag8_t flags;
|
||||
static ufast8_t linesWritePos; // Position where we write the next cached line move
|
||||
ufast8_t joinFlags;
|
||||
volatile ufast8_t flags;
|
||||
uint8_t secondSpeed; // for laser intensity or fan control
|
||||
private:
|
||||
flag8_t primaryAxis;
|
||||
fast8_t primaryAxis;
|
||||
ufast8_t dir; ///< Direction of movement. 1 = X+, 2 = Y+, 4= Z+, values can be combined.
|
||||
int32_t timeInTicks;
|
||||
flag8_t halfStep; ///< 4 = disabled, 1 = halfstep, 2 = fulstep
|
||||
flag8_t dir; ///< Direction of movement. 1 = X+, 2 = Y+, 4= Z+, values can be combined.
|
||||
int32_t delta[E_AXIS_ARRAY]; ///< Steps we want to move.
|
||||
int32_t error[E_AXIS_ARRAY]; ///< Error calculation for Bresenham algorithm
|
||||
float speedX; ///< Speed in x direction at fullInterval in mm/s
|
||||
|
@ -186,18 +184,18 @@ private:
|
|||
float speedZ; ///< Speed in z direction at fullInterval in mm/s
|
||||
float speedE; ///< Speed in E direction at fullInterval in mm/s
|
||||
float fullSpeed; ///< Desired speed mm/s
|
||||
float invFullSpeed; ///< 1.0/fullSpeed for fatser computation
|
||||
float accelerationDistance2; ///< Real 2.0*distanceÜacceleration mm²/s²
|
||||
float invFullSpeed; ///< 1.0/fullSpeed for faster computation
|
||||
float accelerationDistance2; ///< Real 2.0*distance*acceleration mm²/s²
|
||||
float maxJunctionSpeed; ///< Max. junction speed between this and next segment
|
||||
float startSpeed; ///< Staring speed in mm/s
|
||||
float startSpeed; ///< Starting speed in mm/s
|
||||
float endSpeed; ///< Exit speed in mm/s
|
||||
float minSpeed;
|
||||
float distance;
|
||||
#if NONLINEAR_SYSTEM
|
||||
uint8_t numDeltaSegments; ///< Number of delta segments left in line. Decremented by stepper timer.
|
||||
uint8_t numNonlinearSegments; ///< Number of delta segments left in line. Decremented by stepper timer.
|
||||
uint8_t moveID; ///< ID used to identify moves which are all part of the same line
|
||||
int32_t numPrimaryStepPerSegment; ///< Number of primary bresenham axis steps in each delta segment
|
||||
DeltaSegment segments[DELTASEGMENTS_PER_PRINTLINE];
|
||||
int32_t numPrimaryStepPerSegment; ///< Number of primary Bresenham axis steps in each delta segment
|
||||
NonlinearSegment segments[DELTASEGMENTS_PER_PRINTLINE];
|
||||
#endif
|
||||
ticks_t fullInterval; ///< interval at full speed in ticks/step.
|
||||
uint16_t accelSteps; ///< How much steps does it take, to reach the plateau.
|
||||
|
@ -214,7 +212,7 @@ private:
|
|||
int32_t advanceStart;
|
||||
int32_t advanceEnd;
|
||||
#endif
|
||||
uint16_t advanceL; ///< Recomputated L value
|
||||
uint16_t advanceL; ///< Recomputed L value
|
||||
#endif
|
||||
#ifdef DEBUG_STEPCOUNT
|
||||
int32_t totalStepsRemaining;
|
||||
|
@ -222,7 +220,7 @@ private:
|
|||
public:
|
||||
int32_t stepsRemaining; ///< Remaining steps, until move is finished
|
||||
static PrintLine *cur;
|
||||
static volatile uint8_t linesCount; // Number of lines cached 0 = nothing to do
|
||||
static volatile ufast8_t linesCount; // Number of lines cached 0 = nothing to do
|
||||
inline bool areParameterUpToDate()
|
||||
{
|
||||
return joinFlags & FLAG_JOIN_STEPPARAMS_COMPUTED;
|
||||
|
@ -283,6 +281,9 @@ public:
|
|||
{
|
||||
return flags & FLAG_BLOCKED;
|
||||
}
|
||||
inline bool isAllEMotors() {
|
||||
return flags & FLAG_ALL_E_MOTORS;
|
||||
}
|
||||
inline bool isCheckEndstops()
|
||||
{
|
||||
return flags & FLAG_CHECK_ENDSTOPS;
|
||||
|
@ -299,91 +300,135 @@ public:
|
|||
{
|
||||
if(isCheckEndstops())
|
||||
{
|
||||
if(isXNegativeMove() && Printer::isXMinEndstopHit())
|
||||
Endstops::update();
|
||||
if(isXNegativeMove() && Endstops::xMin())
|
||||
setXMoveFinished();
|
||||
if(isYNegativeMove() && Printer::isYMinEndstopHit())
|
||||
setYMoveFinished();
|
||||
if(isXPositiveMove() && Printer::isXMaxEndstopHit())
|
||||
else if(isXPositiveMove() && Endstops::xMax())
|
||||
setXMoveFinished();
|
||||
if(isYPositiveMove() && Printer::isYMaxEndstopHit())
|
||||
if(isYNegativeMove() && Endstops::yMin())
|
||||
setYMoveFinished();
|
||||
else if(isYPositiveMove() && Endstops::yMax())
|
||||
setYMoveFinished();
|
||||
#if FEATURE_Z_PROBE
|
||||
if(Printer::isZProbingActive() && isZNegativeMove() && Endstops::zProbe())
|
||||
{
|
||||
setZMoveFinished();
|
||||
Printer::stepsRemainingAtZHit = stepsRemaining;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
#if MULTI_ZENDSTOP_HOMING
|
||||
if(isZNegativeMove())
|
||||
{
|
||||
if(Endstops::zMin())
|
||||
Printer::multiZHomeFlags &= ~1;
|
||||
if(Endstops::z2MinMax())
|
||||
Printer::multiZHomeFlags &= ~2;
|
||||
if(Printer::multiZHomeFlags == 0)
|
||||
setZMoveFinished();
|
||||
}
|
||||
else if(isZPositiveMove())
|
||||
{
|
||||
if(Endstops::zMin())
|
||||
Printer::multiZHomeFlags &= ~1;
|
||||
if(Endstops::z2MinMax())
|
||||
Printer::multiZHomeFlags &= ~2;
|
||||
if(Printer::multiZHomeFlags == 0) {
|
||||
#if MAX_HARDWARE_ENDSTOP_Z
|
||||
Printer::stepsRemainingAtZHit = stepsRemaining;
|
||||
#endif
|
||||
setZMoveFinished();
|
||||
}
|
||||
}
|
||||
#else
|
||||
if(isZNegativeMove() && Endstops::zMin())
|
||||
{
|
||||
setZMoveFinished();
|
||||
}
|
||||
else if(isZPositiveMove() && Endstops::zMax())
|
||||
{
|
||||
#if MAX_HARDWARE_ENDSTOP_Z
|
||||
Printer::stepsRemainingAtZHit = stepsRemaining;
|
||||
#endif
|
||||
setZMoveFinished();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
#if FEATURE_Z_PROBE
|
||||
if(Printer::isZProbingActive() && isZNegativeMove() && Printer::isZProbeHit())
|
||||
{
|
||||
setZMoveFinished();
|
||||
Printer::stepsRemainingAtZHit = stepsRemaining;
|
||||
else if(Printer::isZProbingActive() && isZNegativeMove()) {
|
||||
Endstops::update();
|
||||
if(Endstops::zProbe())
|
||||
{
|
||||
setZMoveFinished();
|
||||
Printer::stepsRemainingAtZHit = stepsRemaining;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
// Test Z-Axis every step if necessary, otherwise it could easyly ruin your printer!
|
||||
if(isZNegativeMove() && Printer::isZMinEndstopHit())
|
||||
setZMoveFinished();
|
||||
if(isZPositiveMove() && Printer::isZMaxEndstopHit())
|
||||
{
|
||||
#if MAX_HARDWARE_ENDSTOP_Z
|
||||
Printer::stepsRemainingAtZHit = stepsRemaining;
|
||||
#endif
|
||||
setZMoveFinished();
|
||||
}
|
||||
if(isZPositiveMove() && Printer::isZMaxEndstopHit())
|
||||
setZMoveFinished();
|
||||
}
|
||||
|
||||
inline void setXMoveFinished()
|
||||
{
|
||||
#if DRIVE_SYSTEM==CARTESIAN || NONLINEAR_SYSTEM
|
||||
dir&=~16;
|
||||
#if DRIVE_SYSTEM==XY_GANTRY || DRIVE_SYSTEM==YX_GANTRY
|
||||
dir &= ~48;
|
||||
#elif DRIVE_SYSTEM==XZ_GANTRY || DRIVE_SYSTEM==ZX_GANTRY
|
||||
dir &= ~80
|
||||
#else
|
||||
dir&=~48;
|
||||
dir &= ~16;
|
||||
#endif
|
||||
}
|
||||
inline void setYMoveFinished()
|
||||
{
|
||||
#if DRIVE_SYSTEM==CARTESIAN || NONLINEAR_SYSTEM
|
||||
dir&=~32;
|
||||
#if DRIVE_SYSTEM==XY_GANTRY || DRIVE_SYSTEM==YX_GANTRY
|
||||
dir &= ~48;
|
||||
#else
|
||||
dir&=~48;
|
||||
dir &= ~32;
|
||||
#endif
|
||||
}
|
||||
inline void setZMoveFinished()
|
||||
{
|
||||
dir&=~64;
|
||||
#if DRIVE_SYSTEM==XZ_GANTRY || DRIVE_SYSTEM==ZX_GANTRY
|
||||
dir &= ~80
|
||||
#else
|
||||
dir &= ~64;
|
||||
#endif
|
||||
}
|
||||
inline void setXYMoveFinished()
|
||||
{
|
||||
dir&=~48;
|
||||
dir &= ~48;
|
||||
}
|
||||
inline bool isXPositiveMove()
|
||||
{
|
||||
return (dir & X_STEP_DIRPOS)==X_STEP_DIRPOS;
|
||||
return (dir & X_STEP_DIRPOS) == X_STEP_DIRPOS;
|
||||
}
|
||||
inline bool isXNegativeMove()
|
||||
{
|
||||
return (dir & X_STEP_DIRPOS)==XSTEP;
|
||||
return (dir & X_STEP_DIRPOS) == XSTEP;
|
||||
}
|
||||
inline bool isYPositiveMove()
|
||||
{
|
||||
return (dir & Y_STEP_DIRPOS)==Y_STEP_DIRPOS;
|
||||
return (dir & Y_STEP_DIRPOS) == Y_STEP_DIRPOS;
|
||||
}
|
||||
inline bool isYNegativeMove()
|
||||
{
|
||||
return (dir & Y_STEP_DIRPOS)==YSTEP;
|
||||
return (dir & Y_STEP_DIRPOS) == YSTEP;
|
||||
}
|
||||
inline bool isZPositiveMove()
|
||||
{
|
||||
return (dir & Z_STEP_DIRPOS)==Z_STEP_DIRPOS;
|
||||
return (dir & Z_STEP_DIRPOS) == Z_STEP_DIRPOS;
|
||||
}
|
||||
inline bool isZNegativeMove()
|
||||
{
|
||||
return (dir & Z_STEP_DIRPOS)==ZSTEP;
|
||||
return (dir & Z_STEP_DIRPOS) == ZSTEP;
|
||||
}
|
||||
inline bool isEPositiveMove()
|
||||
{
|
||||
return (dir & E_STEP_DIRPOS)==E_STEP_DIRPOS;
|
||||
return (dir & E_STEP_DIRPOS) == E_STEP_DIRPOS;
|
||||
}
|
||||
inline bool isENegativeMove()
|
||||
{
|
||||
return (dir & E_STEP_DIRPOS)==ESTEP;
|
||||
return (dir & E_STEP_DIRPOS) == ESTEP;
|
||||
}
|
||||
inline bool isXMove()
|
||||
{
|
||||
|
@ -411,11 +456,11 @@ public:
|
|||
}
|
||||
inline bool isEOnlyMove()
|
||||
{
|
||||
return (dir & XYZE_STEP)==ESTEP;
|
||||
return (dir & XYZE_STEP) == ESTEP;
|
||||
}
|
||||
inline bool isNoMove()
|
||||
{
|
||||
return (dir & XYZE_STEP)==0;
|
||||
return (dir & XYZE_STEP) == 0;
|
||||
}
|
||||
inline bool isXYZMove()
|
||||
{
|
||||
|
@ -423,25 +468,25 @@ public:
|
|||
}
|
||||
inline bool isMoveOfAxis(uint8_t axis)
|
||||
{
|
||||
return (dir & (XSTEP<<axis));
|
||||
return (dir & (XSTEP << axis));
|
||||
}
|
||||
inline void setMoveOfAxis(uint8_t axis)
|
||||
{
|
||||
dir |= XSTEP<<axis;
|
||||
dir |= XSTEP << axis;
|
||||
}
|
||||
inline void setPositiveDirectionForAxis(uint8_t axis)
|
||||
{
|
||||
dir |= X_DIRPOS<<axis;
|
||||
dir |= X_DIRPOS << axis;
|
||||
}
|
||||
inline static void resetPathPlanner()
|
||||
{
|
||||
linesCount = 0;
|
||||
linesPos = linesWritePos;
|
||||
//Davinci Specific, no immediate no printing to avoid to many refresh
|
||||
//Printer::setMenuMode(MENU_MODE_PRINTING,false);
|
||||
//Davinci Specific, no immediate no printing to avoid too many refresh
|
||||
//Printer::setMenuMode(MENU_MODE_PRINTING, false);
|
||||
}
|
||||
// Only called from bresenham -> inside interrupt handle
|
||||
inline void updateAdvanceSteps(speed_t v,uint8_t max_loops,bool accelerate)
|
||||
inline void updateAdvanceSteps(speed_t v, uint8_t max_loops, bool accelerate)
|
||||
{
|
||||
#if USE_ADVANCE
|
||||
if(!Printer::isAdvanceActivated()) return;
|
||||
|
@ -449,20 +494,20 @@ public:
|
|||
long advanceTarget = Printer::advanceExecuted;
|
||||
if(accelerate)
|
||||
{
|
||||
for(uint8_t loop = 0; loop<max_loops; loop++) advanceTarget += advanceRate;
|
||||
if(advanceTarget>advanceFull)
|
||||
for(uint8_t loop = 0; loop < max_loops; loop++) advanceTarget += advanceRate;
|
||||
if(advanceTarget > advanceFull)
|
||||
advanceTarget = advanceFull;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(uint8_t loop = 0; loop<max_loops; loop++) advanceTarget -= advanceRate;
|
||||
if(advanceTarget<advanceEnd)
|
||||
for(uint8_t loop = 0; loop < max_loops; loop++) advanceTarget -= advanceRate;
|
||||
if(advanceTarget < advanceEnd)
|
||||
advanceTarget = advanceEnd;
|
||||
}
|
||||
long h = HAL::mulu16xu16to32(v, advanceL);
|
||||
int tred = ((advanceTarget + h) >> 16);
|
||||
HAL::forbidInterrupts();
|
||||
Printer::extruderStepsNeeded += tred-Printer::advanceStepsSet;
|
||||
Printer::extruderStepsNeeded += tred - Printer::advanceStepsSet;
|
||||
if(tred > 0 && Printer::advanceStepsSet <= 0)
|
||||
Printer::extruderStepsNeeded += Extruder::current->advanceBacklash;
|
||||
else if(tred < 0 && Printer::advanceStepsSet >= 0)
|
||||
|
@ -483,7 +528,7 @@ public:
|
|||
#endif
|
||||
#endif
|
||||
}
|
||||
inline bool moveDecelerating()
|
||||
INLINE bool moveDecelerating()
|
||||
{
|
||||
if(stepsRemaining <= decelSteps)
|
||||
{
|
||||
|
@ -496,21 +541,14 @@ public:
|
|||
}
|
||||
else return false;
|
||||
}
|
||||
inline bool moveAccelerating()
|
||||
INLINE bool moveAccelerating()
|
||||
{
|
||||
return Printer::stepNumber <= accelSteps;
|
||||
}
|
||||
inline bool isFullstepping()
|
||||
INLINE void startXStep()
|
||||
{
|
||||
return halfStep == 4;
|
||||
}
|
||||
inline void startXStep()
|
||||
{
|
||||
#if !(GANTRY)
|
||||
WRITE(X_STEP_PIN,HIGH);
|
||||
#if FEATURE_TWO_XSTEPPER
|
||||
WRITE(X2_STEP_PIN,HIGH);
|
||||
#endif
|
||||
#if !(GANTRY) || defined(FAST_COREXYZ)
|
||||
Printer::startXStep();
|
||||
#else
|
||||
#if DRIVE_SYSTEM == XY_GANTRY || DRIVE_SYSTEM == XZ_GANTRY
|
||||
if(isXPositiveMove())
|
||||
|
@ -540,17 +578,13 @@ public:
|
|||
#ifdef DEBUG_STEPCOUNT
|
||||
totalStepsRemaining--;
|
||||
#endif
|
||||
|
||||
}
|
||||
inline void startYStep()
|
||||
INLINE void startYStep()
|
||||
{
|
||||
#if !(GANTRY) || DRIVE_SYSTEM == ZX_GANTRY || DRIVE_SYSTEM == XZ_GANTRY
|
||||
WRITE(Y_STEP_PIN,HIGH);
|
||||
#if FEATURE_TWO_YSTEPPER
|
||||
WRITE(Y2_STEP_PIN,HIGH);
|
||||
#endif
|
||||
#if !(GANTRY) || DRIVE_SYSTEM == ZX_GANTRY || DRIVE_SYSTEM == XZ_GANTRY || defined(FAST_COREXYZ)
|
||||
Printer::startYStep();
|
||||
#else
|
||||
#if DRIVE_SYSTEM==XY_GANTRY
|
||||
#if DRIVE_SYSTEM == XY_GANTRY
|
||||
if(isYPositiveMove())
|
||||
{
|
||||
Printer::motorX++;
|
||||
|
@ -562,7 +596,7 @@ public:
|
|||
Printer::motorYorZ++;
|
||||
}
|
||||
#endif
|
||||
#if DRIVE_SYSTEM==YX_GANTRY
|
||||
#if DRIVE_SYSTEM == YX_GANTRY
|
||||
if(isYPositiveMove())
|
||||
{
|
||||
Printer::motorX++;
|
||||
|
@ -578,17 +612,15 @@ public:
|
|||
#ifdef DEBUG_STEPCOUNT
|
||||
totalStepsRemaining--;
|
||||
#endif
|
||||
|
||||
}
|
||||
inline void startZStep()
|
||||
INLINE void startZStep()
|
||||
{
|
||||
#if !(GANTRY) || DRIVE_SYSTEM == YX_GANTRY || DRIVE_SYSTEM == XY_GANTRY
|
||||
WRITE(Z_STEP_PIN,HIGH);
|
||||
#if FEATURE_TWO_ZSTEPPER
|
||||
WRITE(Z2_STEP_PIN,HIGH);
|
||||
#endif
|
||||
#if !(GANTRY) || DRIVE_SYSTEM == YX_GANTRY || DRIVE_SYSTEM == XY_GANTRY || defined(FAST_COREXYZ)
|
||||
Printer::startZStep();
|
||||
#else
|
||||
#if DRIVE_SYSTEM==XZ_GANTRY
|
||||
if(isYPositiveMove())
|
||||
#if DRIVE_SYSTEM == XZ_GANTRY
|
||||
if(isZPositiveMove())
|
||||
{
|
||||
Printer::motorX++;
|
||||
Printer::motorYorZ--;
|
||||
|
@ -599,8 +631,8 @@ public:
|
|||
Printer::motorYorZ++;
|
||||
}
|
||||
#endif
|
||||
#if DRIVE_SYSTEM==ZX_GANTRY
|
||||
if(isYPositiveMove())
|
||||
#if DRIVE_SYSTEM == ZX_GANTRY
|
||||
if(isZPositiveMove())
|
||||
{
|
||||
Printer::motorX++;
|
||||
Printer::motorYorZ++;
|
||||
|
@ -611,26 +643,29 @@ public:
|
|||
Printer::motorYorZ--;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
#ifdef DEBUG_STEPCOUNT
|
||||
totalStepsRemaining--;
|
||||
#endif
|
||||
}
|
||||
void updateStepsParameter();
|
||||
inline float safeSpeed();
|
||||
void calculateMove(float axis_diff[],uint8_t pathOptimize);
|
||||
float safeSpeed(fast8_t drivingAxis);
|
||||
void calculateMove(float axis_diff[],uint8_t pathOptimize,fast8_t distanceBase);
|
||||
void logLine();
|
||||
inline long getWaitTicks()
|
||||
INLINE long getWaitTicks()
|
||||
{
|
||||
return timeInTicks;
|
||||
}
|
||||
inline void setWaitTicks(long wait)
|
||||
INLINE void setWaitTicks(long wait)
|
||||
{
|
||||
timeInTicks = wait;
|
||||
}
|
||||
|
||||
static inline bool hasLines()
|
||||
static INLINE bool hasLines()
|
||||
{
|
||||
return linesCount;
|
||||
}
|
||||
static inline void setCurrentLine()
|
||||
static INLINE void setCurrentLine()
|
||||
{
|
||||
cur = &lines[linesPos];
|
||||
#if CPU_ARCH==ARCH_ARM
|
||||
|
@ -638,30 +673,31 @@ public:
|
|||
#endif
|
||||
}
|
||||
// Only called from within interrupts
|
||||
static inline void removeCurrentLineForbidInterrupt()
|
||||
static INLINE void removeCurrentLineForbidInterrupt()
|
||||
{
|
||||
linesPos++;
|
||||
if(linesPos >= PRINTLINE_CACHE_SIZE) linesPos=0;
|
||||
if(linesPos >= PRINTLINE_CACHE_SIZE) linesPos = 0;
|
||||
cur = NULL;
|
||||
#if CPU_ARCH==ARCH_ARM
|
||||
#if CPU_ARCH == ARCH_ARM
|
||||
nlFlag = false;
|
||||
#endif
|
||||
HAL::forbidInterrupts();
|
||||
//Davinci Specific, no immediate no printing to avoid to many refresh
|
||||
//be sure linescount is not 0 before decremente
|
||||
if (linesCount>0) --linesCount;
|
||||
if (linesCount > 0) --linesCount;
|
||||
// if(!linesCount)
|
||||
// Printer::setMenuMode(MENU_MODE_PRINTING,false);
|
||||
}
|
||||
static inline void pushLine()
|
||||
static INLINE void pushLine()
|
||||
{
|
||||
linesWritePos++;
|
||||
if(linesWritePos >= PRINTLINE_CACHE_SIZE) linesWritePos = 0;
|
||||
Printer::setMenuMode(MENU_MODE_PRINTING,true);
|
||||
Printer::setMenuMode(MENU_MODE_PRINTING, true);
|
||||
InterruptProtectedBlock noInts;
|
||||
linesCount++;
|
||||
}
|
||||
static uint8_t getLinesCount() {
|
||||
static uint8_t getLinesCount()
|
||||
{
|
||||
InterruptProtectedBlock noInts;
|
||||
return linesCount;
|
||||
}
|
||||
|
@ -672,29 +708,34 @@ public:
|
|||
static inline void computeMaxJunctionSpeed(PrintLine *previous,PrintLine *current);
|
||||
static int32_t bresenhamStep();
|
||||
static void waitForXFreeLines(uint8_t b=1, bool allowMoves = false);
|
||||
static inline void forwardPlanner(uint8_t p);
|
||||
static inline void backwardPlanner(uint8_t p,uint8_t last);
|
||||
static inline void forwardPlanner(ufast8_t p);
|
||||
static inline void backwardPlanner(ufast8_t p,ufast8_t last);
|
||||
static void updateTrapezoids();
|
||||
static uint8_t insertWaitMovesIfNeeded(uint8_t pathOptimize, uint8_t waitExtraLines);
|
||||
#if !NONLINEAR_SYSTEM
|
||||
static void queueCartesianMove(uint8_t check_endstops,uint8_t pathOptimize);
|
||||
static void moveRelativeDistanceInSteps(int32_t x,int32_t y,int32_t z,int32_t e,float feedrate,bool waitEnd,bool check_endstop);
|
||||
static void moveRelativeDistanceInStepsReal(int32_t x,int32_t y,int32_t z,int32_t e,float feedrate,bool waitEnd);
|
||||
#if DISTORTION_CORRECTION
|
||||
static void queueCartesianSegmentTo(uint8_t check_endstops, uint8_t pathOptimize);
|
||||
#endif
|
||||
#endif
|
||||
static void moveRelativeDistanceInSteps(int32_t x,int32_t y,int32_t z,int32_t e,float feedrate,bool waitEnd,bool check_endstop,bool pathOptimize = true);
|
||||
static void moveRelativeDistanceInStepsReal(int32_t x,int32_t y,int32_t z,int32_t e,float feedrate,bool waitEnd,bool pathOptimize = true);
|
||||
#if ARC_SUPPORT
|
||||
static void arc(float *position, float *target, float *offset, float radius, uint8_t isclockwise);
|
||||
#endif
|
||||
static inline void previousPlannerIndex(uint8_t &p)
|
||||
static INLINE void previousPlannerIndex(ufast8_t &p)
|
||||
{
|
||||
p = (p ? p-1 : PRINTLINE_CACHE_SIZE-1);
|
||||
p = (p ? p - 1 : PRINTLINE_CACHE_SIZE - 1);
|
||||
}
|
||||
static inline void nextPlannerIndex(uint8_t& p)
|
||||
static INLINE void nextPlannerIndex(ufast8_t& p)
|
||||
{
|
||||
p = (p == PRINTLINE_CACHE_SIZE - 1 ? 0 : p + 1);
|
||||
}
|
||||
#if NONLINEAR_SYSTEM
|
||||
static uint8_t queueDeltaMove(uint8_t check_endstops,uint8_t pathOptimize, uint8_t softEndstop);
|
||||
static uint8_t queueNonlinearMove(uint8_t check_endstops,uint8_t pathOptimize, uint8_t softEndstop);
|
||||
static inline void queueEMove(int32_t e_diff,uint8_t check_endstops,uint8_t pathOptimize);
|
||||
inline uint16_t calculateDeltaSubSegments(uint8_t softEndstop);
|
||||
static inline void calculateDirectionAndDelta(int32_t difference[], flag8_t *dir, int32_t delta[]);
|
||||
inline uint16_t calculateNonlinearSubSegments(uint8_t softEndstop);
|
||||
static inline void calculateDirectionAndDelta(int32_t difference[], ufast8_t *dir, int32_t delta[]);
|
||||
static inline uint8_t calculateDistance(float axis_diff[], uint8_t dir, float *distance);
|
||||
#if SOFTWARE_LEVELING && DRIVE_SYSTEM == DELTA
|
||||
static void calculatePlane(int32_t factors[], int32_t p1[], int32_t p2[], int32_t p3[]);
|
||||
|
|
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
|
@ -99,7 +99,7 @@ works, use the ascii charset 0 as fallback. Not the nicest for everything but wo
|
|||
|
||||
/**
|
||||
What display type do you use?
|
||||
0 = No display
|
||||
0 = No display - do not use here. Set FEATURE_CONTROLLER 0 instead
|
||||
1 = LCD Display with 4 bit data bus
|
||||
2 = LCD Display with 8 bit data bus (currently not implemented, fallback to 1)
|
||||
3 = LCD Display with I2C connection, 4 bit mode
|
||||
|
@ -113,7 +113,31 @@ What display type do you use?
|
|||
|
||||
#if UI_DISPLAY_TYPE == DISPLAY_U8G // Special case for graphic displays
|
||||
|
||||
#define U8GLIB_ST7920 // Currently only this display from u8g lib is included.
|
||||
// You need to define which controller you use and set pins accodringly
|
||||
|
||||
// For software spi assign these definitions
|
||||
// SCK Pin: UI_DISPLAY_D4_PIN
|
||||
// Mosi Pin: UI_DISPLAY_ENABLE_PIN
|
||||
// CD Pin: UI_DISPLAY_RS_PIN
|
||||
|
||||
// ST7920 with software SPI
|
||||
#define U8GLIB_ST7920
|
||||
// SSD1306 with software SPI
|
||||
//#define U8GLIB_SSD1306_SW_SPI
|
||||
// SH1106 with software SPI
|
||||
// U8GLIB_SH1106_SW_SPI
|
||||
// SSD1306 over I2C using hardware I2C pins
|
||||
//#define U8GLIB_SSD1306_I2C
|
||||
// For the 8 bit ks0108 display you need to set these pins
|
||||
// UI_DISPLAY_D0_PIN,UI_DISPLAY_D1_PIN,UI_DISPLAY_D2_PIN,UI_DISPLAY_D3_PIN,UI_DISPLAY_D4_PIN,UI_DISPLAY_D5_PIN,UI_DISPLAY_D6_PIN,UI_DISPLAY_D7_PIN
|
||||
// UI_DISPLAY_ENABLE_PIN,UI_DISPLAY_CS1,UI_DISPLAY_CS2,
|
||||
// UI_DISPLAY_DI,UI_DISPLAY_RW_PIN,UI_DISPLAY_RESET_PIN
|
||||
//#define U8GLIB_KS0108
|
||||
//#define U8GLIB_KS0108_FAST
|
||||
// UI_DISPLAY_RS_PIN = CS
|
||||
// UI_DISPLAY_D5_PIN = A0
|
||||
//#define U8GLIB_ST7565_NHD_C2832_HW_SPI
|
||||
|
||||
#define UI_LCD_WIDTH 128
|
||||
#define UI_LCD_HEIGHT 64
|
||||
|
||||
|
@ -220,6 +244,13 @@ Define the pin
|
|||
|
||||
#define UI_BACKLIGHT_PIN 78
|
||||
|
||||
// Special pins for some u8g driven display
|
||||
|
||||
//#define UI_DISPLAY_CS1 59
|
||||
//#define UI_DISPLAY_CS2 59
|
||||
//#define UI_DISPLAY_DI 59
|
||||
//#define UI_DISPLAY_RW_PIN 59
|
||||
//#define UI_DISPLAY_RESET_PIN 59
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -368,7 +399,7 @@ void uiInitKeys() {
|
|||
// UI_KEYS_INIT_MATRIX(32,47,45,43,41,39,37,35);
|
||||
#endif
|
||||
}
|
||||
void uiCheckKeys(int &action) {
|
||||
void uiCheckKeys(uint16_t &action) {
|
||||
#if UI_HAS_KEYS!=0
|
||||
|
||||
//Davinci Specific, for cheat key
|
||||
|
@ -412,7 +443,7 @@ inline void uiCheckSlowEncoder() {
|
|||
HAL::i2cWrite(0x12); // GIOA
|
||||
HAL::i2cStop();
|
||||
HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS+I2C_READ);
|
||||
unsigned int keymask = HAL::i2cReadAck();
|
||||
uint16_t keymask = HAL::i2cReadAck();
|
||||
keymask = keymask + (HAL::i2cReadNak()<<8);
|
||||
#endif
|
||||
HAL::i2cStop();
|
||||
|
@ -420,8 +451,7 @@ inline void uiCheckSlowEncoder() {
|
|||
UI_KEYS_I2C_CLICKENCODER_LOW_REV(_BV(2),_BV(0)); // click encoder on pins 0 and 2. Phase is connected with gnd for signals.
|
||||
#endif
|
||||
}
|
||||
|
||||
void uiCheckSlowKeys(int &action) {
|
||||
void uiCheckSlowKeys(uint16_t &action) {
|
||||
#if defined(UI_HAS_I2C_KEYS) && UI_HAS_KEYS!=0
|
||||
#if UI_DISPLAY_I2C_CHIPTYPE==0
|
||||
HAL::i2cStartWait(UI_I2C_KEY_ADDRESS+I2C_READ);
|
||||
|
@ -432,7 +462,7 @@ void uiCheckSlowKeys(int &action) {
|
|||
HAL::i2cWrite(0x12); // GPIOA
|
||||
HAL::i2cStop();
|
||||
HAL::i2cStartWait(UI_DISPLAY_I2C_ADDRESS+I2C_READ);
|
||||
unsigned int keymask = HAL::i2cReadAck();
|
||||
uint16_t keymask = HAL::i2cReadAck();
|
||||
keymask = keymask + (HAL::i2cReadNak()<<8);
|
||||
#endif
|
||||
HAL::i2cStop();
|
||||
|
@ -459,3 +489,6 @@ void uiCheckSlowKeys(int &action) {
|
|||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
Plik diff jest za duży
Load Diff
|
@ -55,7 +55,7 @@
|
|||
#if MODEL==0
|
||||
#define ORIG_E0_ENABLE_PIN 128
|
||||
#else
|
||||
#define ORIG_E0_ENABLE_PIN 124 // no idea if it is good value but can avoid conflict with ORIG_Z_MIN_PIN for 2.0A, another value to try is 85
|
||||
#define ORIG_E0_ENABLE_PIN 124
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -65,9 +65,6 @@
|
|||
#define ORIG_FAN2_PIN 4
|
||||
|
||||
//additionnal PINS
|
||||
#define X_MAX_PIN -1
|
||||
#define Y_MAX_PIN -1
|
||||
#define Z_MAX_PIN -1
|
||||
#define LED_PIN -1
|
||||
#if MODEL==0
|
||||
#define LIGHT_PIN 85
|
||||
|
@ -81,17 +78,23 @@
|
|||
#else
|
||||
#define TOP_SENSOR_PIN 64
|
||||
#endif
|
||||
#if DAVINCI==4
|
||||
#if DAVINCI == 4
|
||||
#define BADGE_LIGHT_PIN 6
|
||||
#define LASER1_PIN 101
|
||||
#define LED_LASER1_PIN 108
|
||||
#define LASER2_PIN 2
|
||||
#define LED_LASER2_PIN 7
|
||||
#define TABLE_HOME_PIN 5
|
||||
#else
|
||||
#define BADGE_LIGHT_PIN -1
|
||||
#endif
|
||||
#undef SDSS
|
||||
#define SDSS 55
|
||||
#define MOSI_PIN 43
|
||||
#define MISO_PIN 73
|
||||
#define SCK_PIN 42
|
||||
#define SDPOWER -1
|
||||
#define SDCARDDETECT 74
|
||||
#define ORIG_SDCARDDETECT 74
|
||||
#define SDSUPPORT true
|
||||
#define SDCARDDETECTINVERTED 0
|
||||
#define DUE_SOFTWARE_SPI
|
||||
|
@ -118,9 +121,7 @@
|
|||
//USB Connection
|
||||
#define RFSERIAL SerialUSB // Native USB Port of the due
|
||||
//EEPROM is on SDCard
|
||||
#define EEPROM_AVAILABLE 1
|
||||
//EEprom on SDCard
|
||||
#define SDEEPROM
|
||||
#define EEPROM_AVAILABLE EEPROM_SDCARD
|
||||
|
||||
#define E0_PINS ORIG_E0_STEP_PIN,ORIG_E0_DIR_PIN,ORIG_E0_ENABLE_PIN,
|
||||
#define E1_PINS ORIG_E1_STEP_PIN,ORIG_E1_DIR_PIN,ORIG_E1_ENABLE_PIN,
|
||||
|
|
Ładowanie…
Reference in New Issue