Merge devt branch to move to 0.92.10 base

pull/22/merge v0.92.10rc1
luc lebosse 2016-08-29 10:40:14 +02:00
rodzic a1d7816570
commit 5b7f1f5e4b
50 zmienionych plików z 47691 dodań i 15318 usunięć

1
.gitignore vendored
Wyświetl plik

@ -25,3 +25,4 @@ Configuration_*.h
Repetier.depend
Repetier.layout
activate*.bat
~$Translate.xlsx

Wyświetl plik

@ -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:

Wyświetl plik

@ -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.

BIN
Translate.xlsx 100644

Plik binarny nie jest wyświetlany.

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -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()
{
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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()
{
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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 }

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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();

Wyświetl plik

@ -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;
}*/
}

Wyświetl plik

@ -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:
};

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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);

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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;

Wyświetl plik

@ -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

Wyświetl plik

@ -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"

Wyświetl plik

@ -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,&params);
//*(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);
}

Wyświetl plik

@ -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 ====================

Wyświetl plik

@ -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
};
//------------------------------------------------------------------------------
/**

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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

Wyświetl plik

@ -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[]);

Wyświetl plik

@ -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

Wyświetl plik

@ -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,