442 Commits

Author SHA1 Message Date
Kevin O'Connor
8f1d0c2a7c docs: Note version 0.4.0 release
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-05-03 14:32:36 -04:00
Kevin O'Connor
02549c9299 docs: Make it clear a RESTART is likely needed in Installation document
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-05-03 11:15:27 -04:00
Kevin O'Connor
98f2adbcb5 extruder: Rework maximum retraction check
On a retract move (which are common during "wipe" operations), treat
the move as if it were an extrude only move.  It's valid for a retract
move to reverse more filament then it would be practical to push.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-05-02 08:57:38 -04:00
Kevin O'Connor
c9d21574d8 gcode: Check for invalid speeds
Raise an error if the move speed is set to a zero or negative value.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-05-02 07:54:48 -04:00
Kevin O'Connor
253517096e extruder: Extend over extrusion checks to retractions
Ensure a move with a retraction (negative extrude) is also checked for
sane extrusion rates.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-05-02 07:54:48 -04:00
Kevin O'Connor
0fa35254c6 msgproto: Wrap strings passed via output() in repr()
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-05-02 07:54:48 -04:00
Kevin O'Connor
fc9fb7473c gcode: Don't report an error if turning off an unknown fan or heater
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-05-01 15:02:27 -04:00
Kevin O'Connor
31ca2331d2 queuelogger: Add critical information to each logfile on rollover
When the log file does a rollover, start the top of the log with
critical system information (eg, software versions).

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-05-01 14:48:44 -04:00
Kevin O'Connor
b5062a07d1 docs: Recommend users stop klipper before flashing the micro-controller
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-05-01 12:08:45 -04:00
Kevin O'Connor
4112007314 docs: Reword XY+Z delta moves in Kinematics
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-05-01 11:58:32 -04:00
Kevin O'Connor
a3162b17d9 docs: Use only single space at start of new sentence
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-05-01 11:58:32 -04:00
Kevin O'Connor
e177d4f70d docs: Reword smoothed look-ahead description in Kinematics
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-05-01 11:58:32 -04:00
Kevin O'Connor
631b0e6c37 docs: Improve wording of slow lookahead description
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-27 16:05:26 -04:00
Kevin O'Connor
a7f339ad1c docs: Improve documentation for those starting in docs/
Those that reach Klipper via github may jump directly to the docs/
directory in search of documentation.  Add README.md and rework
Overview.md with that in mind.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-27 16:05:26 -04:00
Kevin O'Connor
c1c0b2dd38 docs: Avoid using "firmware" in the documentation
The term "firmware" is ambiguous - it could refer to the entire
project (host and micro-controller software) or to just the
micro-controller software.  Avoid the term in the documentation.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-27 15:59:33 -04:00
Kevin O'Connor
d7a1111955 docs: Add backticks around commands in Firmware Commands
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-27 12:10:38 -04:00
Kevin O'Connor
d73340474b docs: Use "look-ahead" instead of "lookahead" in Code Overview
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-27 12:02:15 -04:00
Kevin O'Connor
4f7237de44 docs: Update Firmware Commands document with an integer example
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-27 12:00:10 -04:00
Kevin O'Connor
4096745a58 docs: Use a markdown link to docs/prints/square.stl
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-27 12:00:09 -04:00
Kevin O'Connor
a97e074022 docs: Kinematics document image updates
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-27 12:00:09 -04:00
Kevin O'Connor
917c6aa94a docs: Todo updates
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-27 09:52:38 -04:00
Kevin O'Connor
05bd6fda7e config: Add a sample config file for RAMBo boards
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-26 11:51:40 -04:00
Kevin O'Connor
7c78de989d config: Add a sample config file for RAMPS boards
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-26 11:48:35 -04:00
Kevin O'Connor
35a6d9ba87 gcode: Sort the order of commands in HELP
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-26 10:44:22 -04:00
Kevin O'Connor
c63754fc32 gcode: Limit build_handlers() method to just building available commands
The set_printer_ready() can be called from a background thread on a
shutdown event, so don't try to lookup the printer components in that
case.  Simplify build_handlers() so that it no longer tests for
components being available - test for component availability in the
command handlers.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-26 10:31:58 -04:00
Kevin O'Connor
ccb93068fe msgproto: Rework dump() so it also works with params
Always call the regular .parse() method for each message type during
dump() - add a new .format_params() method for dumping a verbose
representation of the parsed message.  This allows the new
format_params() to also be used with data already parsed.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-25 13:58:13 -04:00
Kevin O'Connor
a6fe355801 console: Automatically convert float values to int during evaluation
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-25 12:26:13 -04:00
Kevin O'Connor
fe11c3e348 console: Use stdout.write() instead of print
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-25 12:26:13 -04:00
Kevin O'Connor
56d4422d31 docs: Reword alternate linux machine in installation instructions
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-24 09:39:40 -04:00
Kevin O'Connor
e507848a8f docs: Remove "experimental" from descriptions
The Klipper software has progressed to the point where it does not
need to be described as "experimental" software.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-24 09:31:39 -04:00
Kevin O'Connor
70599667cb docs: Installation updates
Recommend using 'make flash' and clean up the octoprint instructions.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-24 09:21:21 -04:00
Kevin O'Connor
1878da228d build: Add workaround to suppress broken avr-gcc "misspelled" warnings
Detect avr gcc v4.8.1 and then disable warnings during the klipper.o
linking to suppress bogus "misspelled signal handler" warnings.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-24 08:54:10 -04:00
Kevin O'Connor
37865d69a2 basecmd: Add debugging commands for testing communication
Add "debug_ping" and "debug_nop" testing commands.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-23 13:37:49 -04:00
Kevin O'Connor
83eba902a3 build: Support makefile rule with default flashing commands
Support a "make flash FLASH_DEVICE=/dev/ttyACM0" rule with the default
commands for flashing a device.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-21 11:01:07 -04:00
Kevin O'Connor
ec805aee2e scripts: Add octopi installation scripts
Add a system startup script so that Klipper can automatically start at
boot time.  Create an installation script that will install the system
dependencies and the startup script.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-21 10:14:27 -04:00
Kevin O'Connor
167b18b58f gcode: Ignore M21 command
No need to recommend users disable "SD card support" in octoprint -
instead, just ignore the M21 command.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-20 10:11:10 -04:00
Kevin O'Connor
4b1a530330 stepcompress: Simplify delta Z only move calculations
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-20 00:56:18 -04:00
Kevin O'Connor
19ffaa9ff0 docs: Reword parts of the pressure advance kinematics description.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-19 20:48:23 -04:00
Kevin O'Connor
0f5167a407 docs: Misc image updates
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-19 19:55:50 -04:00
Kevin O'Connor
563ab5caa5 docs: Add info on delta acceleration limits
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-19 19:54:48 -04:00
Kevin O'Connor
db5b5f121c docs: Add initial Pressure Advance tuning document
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-19 16:02:11 -04:00
Kevin O'Connor
1f417a8441 docs: Update Todo - initial kinematic document written
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-15 22:59:34 -04:00
Kevin O'Connor
b74b09ea7a docs: Updates to Features document
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-15 22:52:36 -04:00
Kevin O'Connor
2cce67ad84 docs: Add initial Kinematics document
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-15 22:26:03 -04:00
Kevin O'Connor
2cb935c300 mcu: No need to log mcu_stats debugging
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-14 10:43:14 -04:00
Kevin O'Connor
b9623c1128 klippy: Don't log stats when the printer is idle
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-14 10:38:37 -04:00
Kevin O'Connor
7a386cff7d mcu: Change "Synchronizing mcu clock" logging to debug
Always log the last synchronized clock during a shutdown event, and
use debug level for normal reports.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-14 10:06:11 -04:00
Kevin O'Connor
839725e3c5 queuelogger: Automatically roll log file
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-14 09:58:34 -04:00
Kevin O'Connor
8920479f85 klippy: Remove CLEAR_SHUTDOWN command
Advice users to issue a FIRMWARE_RESTART command on a printer shutdown
event, and remove support for CLEAR_SHUTDOWN.  A full mcu reset is
preferable and it simplifies the interface.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-13 14:53:41 -04:00
Kevin O'Connor
4c25eae9b4 mcu: Make sure a FIRMWARE_RESTART actually resets the mcu
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-13 14:29:18 -04:00
Kevin O'Connor
a3a45b5037 docs: Update Todo - RPi power over USB now implemented
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-13 14:18:48 -04:00
Kevin O'Connor
dc645d76b4 docs: Reword and reformat parts of move code flow in Code_Overview
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-13 14:08:02 -04:00
Kevin O'Connor
daff83ee9a hub-ctrl: Add support for micro-controller reset via RPi usb power toggling
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-13 13:20:13 -04:00
Kevin O'Connor
9f9e3e61d6 mcu: Support reset command
Extend the FIRMWARE_RESTART command so that it can use the firmware
"reset" command instead of the "arduino" mechanism.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-13 13:20:13 -04:00
Kevin O'Connor
1592395036 reactor: Fix bug causing end() to not always work
Only set the self._process flag in run() not _dispatch_loop().

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-13 13:20:13 -04:00
Kevin O'Connor
8491b1f86a docs: Update Features document with latest performance benchmarks
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-11 13:53:33 -04:00
Kevin O'Connor
a7b4d70cc6 docs: Add documentation on how to run the graphstats.py script
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-11 13:41:11 -04:00
Kevin O'Connor
fa193e9618 graphstats: The times are no longer in UTC time
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-11 13:40:25 -04:00
Kevin O'Connor
050008f3c8 docs: Update Debugging.md file with python virtual env setup
Direct readers to the main Installation file to setup the python
virtual environment and remove the outdated instructions in the
Debugging file.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-11 12:49:12 -04:00
Kevin O'Connor
70e53cb080 docs: Update Firmware_Commands with recent end stop changes
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-11 12:36:29 -04:00
Kevin O'Connor
7b03b04c78 klippy: Support minimum/maximum value checks on configuration variables
Verify that numeric parameters are in a sane range when reading the
config.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-11 11:42:55 -04:00
Kevin O'Connor
7a7b98cc31 sam3x8e: Rework adc pin search to be more clear
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-11 10:01:22 -04:00
Kevin O'Connor
15d5837322 avr: Rework adc and pwm pin search to be more clear
Rework the pin search loop.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-11 10:01:22 -04:00
Kevin O'Connor
f9ebb8b23e avr: Move code around in gpio.c
Move the PWM, ADC, and SPI pin tables closer to their corresponding
code.  This is code movement only - no code changes.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-11 10:00:54 -04:00
Kevin O'Connor
77b94451de avr: Fix irqstatus_t typo in gpio_pwm_setup
The flags and cs variables should be uint8_t not irqstatus_t.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-11 09:49:35 -04:00
Kevin O'Connor
ca6245e974 docs: Update Code Overview document with code flow for a typical move
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-10 22:10:49 -04:00
Kevin O'Connor
1cdddeec30 stepcompress: Add comment on common suffixes and units
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-07 20:22:32 -04:00
Kevin O'Connor
657c908f88 stepcompress: Modify check_expand() into check_push()
Add the new item at the same time as checking if there is space in the
queue.

Also, update the default optimization level of c_helper.so to O2 to
improve the compiled code layout.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-07 19:05:04 -04:00
Kevin O'Connor
d7a0e22d59 stepcompress: Remove step_dist from stepcompress_push_delta()
Pass the step direction explicitly to the low-level delta kinematic C
code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-07 15:08:42 -04:00
Kevin O'Connor
33b809714f delta: Do reverse direction checking in C code
Calculate where a tower must reverse direction during a move in the C
code instead of the delta.py kinematic code.  This simplifies the
python code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-07 15:05:41 -04:00
Kevin O'Connor
b915a2ad7d delta: Make it clear that a "virtual tower" is created
The delta code calculates a "virtual tower" along the line of
movement.  Rework the variable names and comments to make it clear
that this is occurring.

It is not necessary to pass the start_pos variable to the C code as it
is simple to update the start_pos at the start of each movement.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-07 15:05:41 -04:00
Kevin O'Connor
85ed5cef7f stepcompress: Merge stepcompress_delta_const and stepcompress_delta_accel
It's not necessary to have separate C delta kinematic functions for
constant acceleration and constant velocity as constant velocity can
be obtained by using a constant acceleration of zero.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-07 14:47:00 -04:00
Kevin O'Connor
df42b0d1ac stepcompress: Pass delta velocity and acceleration directly to C code
Update the C delta kinematic code to take velocity and acceleration
directly in step distances and clock ticks.  This simplifies the
mcu.py python code as it only needs to do unit and axis conversion.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-07 14:43:48 -04:00
Kevin O'Connor
98add22891 stepcompress: Merge stepcompress_push_accel() and stepcompress_push_const()
It's not necessary to have separate C functions for constant
acceleration and constant velocity as constant velocity can be
obtained by using a constant acceleration of zero.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-07 14:43:25 -04:00
Kevin O'Connor
1d81bf5596 stepcompress: Pass constant velocity and acceleration directly to C code
Update the C code to take velocity and acceleration directly in step
distances and clock ticks.  This simplifies the mcu.py python code as
it only needs to do unit and axis conversion.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-07 13:57:24 -04:00
Kevin O'Connor
e4153a536f mcu: Change mcu_stepper.set_position() to take a location in millimeters
Update the set_position() method to convert from millimeters to
absolute step position.

Also, update PrinterStepper.get_homed_offset() and
mcu_stepper.get_commanded_position() to return millimeters.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-07 13:44:17 -04:00
Kevin O'Connor
79f31238b0 mcu: Don't export the commanded_position variable from mcu_stepper
Now that the kinematic classes call the mcu_stepper with millimeters
and seconds it is no longer necessary for them to directly access the
stepper's position in absolute steps.  Rename
mcu_stepper.commanded_position to mcu_stepper._commanded_pos to make
clear it is not a variable intended to be externally accessed.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-07 13:44:17 -04:00
Kevin O'Connor
8c712d959d mcu: Pass delta velocity and acceleration directly to mcu_stepper
Rework the parameters of step_delta_const() and step_delta_accel() so
that they take velocity and acceleration directly in millimeters and
seconds.  This simplifies the delta.py kinematic code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-07 13:44:04 -04:00
Kevin O'Connor
c4b1a79db2 mcu: Pass constant velocity and acceleration directly to mcu_stepper
Rename step_sqrt/step_factor to step_accel/step_const and have them
directly take the velocity and acceleration in millimeters and
seconds.  This simplifies the kinematic classes.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-07 13:43:56 -04:00
Kevin O'Connor
47f12f107d stepcompress: Move stepcompress_push_* functions to their own section
This is only code movement; no code changes.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-07 13:26:39 -04:00
Kevin O'Connor
bfad970e4d mcu: Rename self.ffi_lib to self._ffi_lib
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-04 10:13:02 -04:00
Kevin O'Connor
49bdc6fbd1 corexy: Initial corexy kinematic implementation
Add initial support for corexy kinematics.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-03 17:27:14 -04:00
Kevin O'Connor
57f279677f endstop: Support halting more than one stepper on trigger
Extend the endstop code so that more than one stepper can be halted
during endstop homing.  Some kinematic setups (eg, corexy) require an
endstop to support this.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-03 17:27:10 -04:00
Kevin O'Connor
fff73c7735 avr: Invert diff in timer checks
Minor optimization on avr.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-03 10:39:49 -04:00
Kevin O'Connor
e44678ceba avr: Implement reset command
Support restarting the mcu using the watchdog feature of AVR chips via
a new reset command.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-02 23:19:29 -04:00
Kevin O'Connor
85c0e9c574 sam3x8e: Implement reset command
Support restarting the mcu via a new reset command.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-02 23:19:25 -04:00
Kevin O'Connor
0c3ec7f9a5 avr: Do not use --relax linker option
The relax option corrupts the compilation on at least some versions of
gcc/binutils (eg, on fedora's avr-gcc 6.2.0 / binutils 2.27) due to
corruption of switch tables that use jump offsets.  This issue is also
the root cause that resulted in commit d67f962a.  Since the --relax
option provides minimal size / performance improvements it can simply
be dropped.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-02 23:19:19 -04:00
Kevin O'Connor
74e15b2eb5 checkstack: Be more flexible in finding the timer irq function
If __vector_13 doesn't exist then try __vector_17.  If neither exists
then handle that gracefully.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-02 23:19:02 -04:00
Kevin O'Connor
565861f680 reactor: Support pause() command even when the reactor is not running
If the reactor isn't running then implement pause using the system
sleep command.  This simplifies the users of pause().

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-04-01 12:26:24 -04:00
Kevin O'Connor
7c991399ac timer: Remove dup timer_shutdown code
Commmit a1c61563 renamed timer_shutdown() to timer_reset() but
neglected to delete timer_shutdown().

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-31 19:20:45 -04:00
Kevin O'Connor
384c853a39 docs: Update benchmark results in Features document
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-31 17:50:36 -04:00
Kevin O'Connor
c0380d0280 stepper: Disable homing_endstop_accuracy errors on debug runs
If klippy is started in file output debugging, disable the
homing_endstop_accuracy error check.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-31 14:38:09 -04:00
Kevin O'Connor
a1c61563a0 avr: Fix bug causing timer_read_time() to not be in sync with scheduler
Commit 16e3dbb1 changed the avr implementation of timer_read_time().
Unfortunately, it raised the possibility for timer_read_time() to be
out of sync with the scheduler's understanding of the current time.
In particular, it was common for the timer irq to overflow the 16bit
hardware counter once at startup, and this would lead to
timer_read_time() always returning a time ~4ms ahead of the scheduler
on 16Mhz chips.  This resulted in "Move queue empty" errors.

To resolve this issue, only increment timer_high from timer_periodic()
and make sure the timer irqs start immediately after timer_init().

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-31 14:36:57 -04:00
Kevin O'Connor
aa0f1aaeb2 toolhead: Increase the motor_off_time default to 10 minutes
Increase the default motor_off_time from 1 minute to 10 minutes.  The
small value is a common source of confusion.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-30 14:09:17 -04:00
Kevin O'Connor
03ddd64b93 config: Decrease example max_z_velocity to 25mm/s
Change the example files for cartesian printers to have a 25mm/s
maximum Z velocity.  It's common to use lead screws for the Z axis on
cartesians and it is unlikely one would want to drive them at 250mm/s.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-30 14:05:05 -04:00
Kevin O'Connor
7fc9ba7d3a mcu: Log the mcu clock each time print_time is synchronized
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-30 12:51:10 -04:00
Kevin O'Connor
63b6bab5c3 sam3x8e: Align the TC0_Handler timer irq handler
The code alignment of the TC0_Handler function seems to noticeably
impact performance benchmarks.  Set the function alignment to 16 bytes
to improve testing consistency.  An alignment of 16 doesn't
necessarily improve performance, but it seems to improve testing
consistency on code changes unrelated to timer dispatch.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-30 12:04:08 -04:00
Kevin O'Connor
eb4eeb6f73 timer_irq: Integrate timer_try_set_next() into timer_dispatch_many()
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-30 11:25:23 -04:00
Kevin O'Connor
6988507998 timer_irq: Rename generic/timer.c to generic/timer_irq.c
Rename the file to make it clear that the code is helper functions for
boards with irq based timers.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-30 11:24:44 -04:00
Kevin O'Connor
65be6d5146 avr: Integrate timer_try_set_next() into the irq handler
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-30 11:24:44 -04:00
Kevin O'Connor
6d05dd07f5 sched: Move timer dispatch loop to board code
Rename sched_timer_kick() to sched_timer_dispatch() and move its loop
into its callers in the board code.  This eliminates the need to
export timer_try_set_next() from the board code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-30 11:24:42 -04:00
Kevin O'Connor
7436ec093a sched: Rename reschedule_timer() to insert_timer() and use in sched_add_timer()
Use the same code in both rescheduling of a timer and adding a new
timer.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-30 10:57:35 -04:00
Kevin O'Connor
2b735daae5 timer: Make sure to reset the timer repeat checks on a shutdown
Reset the timer repeat checks on shutdown, otherwise it is possible to
get into an infinite shutdown loop.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-30 10:57:35 -04:00
Kevin O'Connor
f8b0c884b0 stepper: Improve performance of scheduled unsteps
On faster MCUs where a delay is needed between step and unstep use a
"busy loop" in the scheduler instead of trying to schedule to the
unstep time.  This reduces the chance of jitter in the scheduler
accumulating.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-30 10:57:35 -04:00
Kevin O'Connor
18f4d343f5 avr: Remove F_CPU compile time definition
Directly use the Kconfig defined CONFIG_CLOCK_FREQ in the code and
avoid defining F_CPU.  Also, remove the unnecessary O2 option - that
is already the default from the main makefile.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-30 10:56:17 -04:00
Kevin O'Connor
31e78c90e2 avr: Minor optimization for timer_read_time() / timer_periodic()
Tell the compiler that the TOV1 bit is rarely set.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-27 13:37:20 -04:00
Kevin O'Connor
3238256b79 docs: Update benchmark results in Features document
Some additional tweeks to the scheduler has resulted in minor
improvements to the stepper benchmarks.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-26 23:31:33 -04:00
Kevin O'Connor
59b71d5d05 sched: Be explicit with loading of the waketime variable
Explicilty load the timer waketime variable into local variables in
sched_timer_kick().  Change the optimization level from Os to O2.
This helps gcc to avoid unnecessary reloads from memory in the common
stepper_event() case.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-26 22:45:58 -04:00
Kevin O'Connor
4dfa6c6ee4 avr: Introduce optimized timer_is_before()
Provide hand-coded assembler for timer_is_before() on AVR as that code
is used frequently in the time-critical timer dispatch loop and gcc
doesn't do a good job at compiling that comparison code.  Remove the
no longer needed waketime+1 hack from reschedule_timer().

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-26 22:45:58 -04:00
Kevin O'Connor
60e488eb17 timer: Allow board code to define its own timer_is_before implementation
Move sched_is_before() from sched.c to timer_is_before() in the board
specific timer code.  This allows the board code to provide its own
definition.

Also, remove the sched_from_us() and sched_read_time() wrapper
functions and change the callers to directly invoke timer_from_us() /
timer_read_time().

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-26 22:45:58 -04:00
Kevin O'Connor
14340ac4df timer: Organize timer_try_set_next() with priority for repeat timers
Organize the code flow to optimize for repeat timers.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-26 22:01:07 -04:00
Kevin O'Connor
efbfc2b1ab avrsim: Catch simulation errors
Request that simulavr throw an exception on a fatal emulation error
instead of exiting the process.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-26 22:01:07 -04:00
Kevin O'Connor
d4f09bc20d checkstack: Updates for newer binutils
Newer versions of binutils report the variable name on memory
accesses.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-26 21:55:24 -04:00
Kevin O'Connor
d67f962a38 command: Simplify sendf() switch
Commit f28eb902 reworked the switch to fix int16 encoding.  However,
at least one version of avr gcc doesn't like that switch layout (it
uses a jump table).  Reorg the switch to avoid that issue.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-26 21:55:24 -04:00
Kevin O'Connor
6de85d02ae serialqueue: Message receive_time must be taken after read()
The est_clock calculation code requires timestamps on status messages
to never be prior to the reception of the message.  The eventtime of
handle_message() is taken before the read() and there is a small
possibility that it could be inaccurate enough to corrupt the
est_clock calculation.  Take a new timestamp when storing receive_time
to prevent this.  This fix prevents some firmware "Move queue empty"
shutdowns.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-24 19:16:33 -04:00
Kevin O'Connor
f28eb902df command: Fix encoding of 16bit signed integers
The code wasn't properly sign-extending 16bit integers which caused
int16_t reports in output() to appear as uint16_t.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-24 15:31:26 -04:00
Kevin O'Connor
9702d522a4 sched: Report the time of a shutdown
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-24 15:05:52 -04:00
Kevin O'Connor
4f710b0470 avrsim: Support pacing the simulation
Support timing the simulation scaled to the system clock.  This can be
used to make the host estimation of the mcu clock more accurate.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-24 13:55:55 -04:00
Kevin O'Connor
5f29787dc7 avrsim: Do IO directly from simulavr callbacks
Don't start/stop the simulavr simulation loop to do IO - instead
implement the IO directly in the serial callback handlers.  This
improves the speed and consistency of the simulation.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-24 11:58:32 -04:00
Kevin O'Connor
1fbb36fa87 serialhdl: Make sure to calculate est_clock before connect() finishes
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-24 11:13:55 -04:00
Kevin O'Connor
3cafcc2bc7 serialqueue: Don't retransmit on a NAK if no sent data is pending
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-24 11:13:55 -04:00
Kevin O'Connor
8d92c898ee stepcompress: Always return 0 on negative number in safe_sqrt()
sqrt() of a negative number in the C code returns NaN.  This value
results in behavior that is difficult to debug.  Always return 0.0
instead as this results in better behavior that is easier to track
down.  Also, on some code paths, safe_sqrt is called on numbers that
are multiplied by very large amounts (eg, 16000000**2) and thus
distinguishing between large and small negative numbers is difficult.
For now, report in the log if the value is below -0.001.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-22 10:54:53 -04:00
Kevin O'Connor
9bf73cd72d extruder: Make sure EXTRUDE_DIFF_IGNORE doesn't trigger due to rounding
The code disables lookahead between two extruding moves with
significantly different extrude ratios.  Unfortunately, it was
possible for very tiny moves to show different extrude ratios just due
to how the slicer implements rounding when it produces the gcode.
Allow lookahead to be enabled between moves with extrude ratios that
are different if they don't noticeably produce more or less extrusion.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-20 14:39:06 -04:00
Kevin O'Connor
f97cf5c3b6 extruder: Avoid maximum extrude cross section errors on infinitesimal moves
Be less likely to raise a "Move exceeds maximum extrusion cross
section" error on very short moves.  It's okay to extrude a little
extra plastic on moves shorter than the nozzle diameter.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-19 21:38:59 -04:00
Kevin O'Connor
5ff2d5aee6 mcu: Defer MCU_adc register_msg until ready to receive messages
Register the callback handler only after it's required state is setup.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-16 14:41:26 -04:00
Kevin O'Connor
1f474742eb klippy: Log python info at start of log
Log the python version and startup command parameters to the log.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-16 14:41:25 -04:00
Kevin O'Connor
0041a0079d stepcompress: Improve check_line() error messages
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-16 13:15:25 -04:00
Kevin O'Connor
9bb8b0c622 toolhead: Don't raise exception from force_shutdown
Catch and ignore any exceptions when trying to shutdown the printer in
toolhead.force_shutdown() - there's a good chance an exception will be
raised as this method is often called after an invalid internal state
is found.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-16 13:15:25 -04:00
Kevin O'Connor
df6d3107f2 stepper: Fix set_min_stop_interval() calculation
The previous calculation was only valid if the stepper is always
commanded to a position that is an exact multiple of the
step_distance.  The safety check was programmed with a value too large
for other commanded positions, which could result in "No next step"
errors.  Fix by changing the calculation to use the worst case
scenario.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-16 13:15:09 -04:00
Kevin O'Connor
cbdc54843d gcode: Catch common gcode parameter errors
Don't force a firmware shutdown on a simple gcode parse error.
Instead, report the error back to the user and otherwise ignore the
command.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-16 13:13:36 -04:00
Kevin O'Connor
d2027cb4a9 serialhdl: Catch SerialException as well as OSError on serial open
Catch the right exceptions so that a retry is possible when attempting
to open the serial port.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-16 12:49:15 -04:00
Kevin O'Connor
e60779bfe1 heater: Force set_pwm of zero when target_temp is zero
Fix a corner case where a residual in the PID could cause a non-zero
pwm request even when the target_temp is zero.  (Which could lead to a
firmware "Missed scheduling of next pwm event" shutdown.)

Simplify the logic for suppressing duplicate pwm updates and make sure
a zero target_temp always results in a zero pwm update on the
following set_pwm calculation.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-16 12:49:15 -04:00
Kevin O'Connor
f66b1ac450 heater: Add support for AD595 type sensors
Add support for sensor chips that produce a voltage that linearly
scales with temperature.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-13 00:48:30 -04:00
Kevin O'Connor
ff6a96665a heater: Rename thermistor_type config name to sensor_type
Rename the thermistor_type and thermistor_pin config variables to
sensor_type and sensor_pin.  This is in preparation for support of
sensors beyond thermistors.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-13 00:46:33 -04:00
Kevin O'Connor
4388a294a4 heater: Handle case where min adc value is less than max adc value
When using a sensor that isn't a thermisistor, the maximum and minimum
adc values may be swapped - handle that case.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-13 00:44:53 -04:00
Kevin O'Connor
d21b9280f0 klippy: Eliminate high-level build_config phase
Now that the mcu objects can be created prior to connecting to the
mcu, it is no longer necessary to separate the init and build_config
phases in the high-level code.  Move the mcu objection creation from
the build_config phase to the init phase and eliminate the
build_config phase.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-13 00:38:17 -04:00
Kevin O'Connor
92649332ce mcu: Delay setting of mcu_stepper.min_stop_interval
Create a separate callback for setting the min_stop_interval.

Also, move the setting of the stepper max_error from the stepper
configs to the mcu config and rename it to max_stepper_error.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-13 00:38:17 -04:00
Kevin O'Connor
be91c1229f gcode: Eliminate build_config() method
Lookup the printer components during the set_printer_ready() callback.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-13 00:38:17 -04:00
Kevin O'Connor
168cb95bd5 mcu: Allow each oid object to define its own build_config() method
Create a build_config() method on each oid object and call it just
after connecting to the MCU.  Move code that requires a connected
state from the oid init to its new build_config method.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-13 00:38:17 -04:00
Kevin O'Connor
1d796a4e24 mcu: Support config mechanism for translating seconds to clock ticks
Introduce a TICKS() macro during config parsing that will translate
time in seconds to time in clock ticks.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-13 00:38:17 -04:00
Kevin O'Connor
8e6d5efdac pins: Simplify pin map alias setup
Use map_pins() to obtain the pin mapping - don't export
mcu_to_pins().  The functionality of mcu_to_pins() can be obtained by
calling map_pins() with name=None.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-13 00:38:15 -04:00
Kevin O'Connor
0f2478b62f docs: Update benchmark results in Features document
Recent scheduler optimizations have made a minor improvement to the
stepper benchmarks.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-11 12:23:24 -05:00
Kevin O'Connor
e5d7e593ec generic: Move generic parts of sam3x8e timer.c to generic directory
Most of sam3x8e/timer.c is going to be platform agnostic for any board
with standard irq handling.  Move the generic code into a new file
generic/timer.c.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-11 12:15:07 -05:00
Kevin O'Connor
69b927bfe9 sched: Move functions within sched.c
Just code movement - no code changes.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-11 11:14:06 -05:00
Kevin O'Connor
944d176856 sched: Rename sched_timer() to sched_add_timer()
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-11 11:14:06 -05:00
Kevin O'Connor
cdd5a772e8 sched: Don't overwrite shutdown reason if shutdown called while shutdown
If a shutdown occurs while the machine is already shutdown, then keep
the original shutdown reason code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-10 23:24:20 -05:00
Kevin O'Connor
0a3c23bcf6 sched: Avoid rescheduling the currently active timer
It's tricky to reschedule the timer irq correctly (due to race
conditions with the irq) and in practice it's very rarely needed.
Handle the special cases in the generic sched.c code so that the board
code doesn't have to handle it.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-10 23:24:15 -05:00
Kevin O'Connor
cb286ede9d sched: Use a sentinel timer at the end of the timer_list
Introduce a dummy sentinel timer object that is always the last item
on timer_list.  This optimizes the timer_list walking code as it no
longer needs to check for NULL when traversing the list.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-10 16:14:49 -05:00
Kevin O'Connor
16e3dbb18c avr: Optimize 16bit timer upscaling
The hardware timer overflow bit can be used to optimize the conversion
from 16bit timers to 32bit timers.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-10 13:31:38 -05:00
Kevin O'Connor
a38437f378 stepper: Introduce stepper_get_position command and remove from endstop.c
Move the logic to calculate and report the stepper's current position
from endstop.c to stepper.c.  This localizes the stepper code into
stepper.c.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-09 14:54:52 -05:00
Kevin O'Connor
8d6ecd9af8 endstop: No need to store pin_value
The pin_value can be stored in the existing flags variable.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-09 14:50:40 -05:00
Kevin O'Connor
342a7096ea basecmd: Remove unimplemented command_reset()
It's better to not have the unimplemented command defined so that the
host can detect when it is actually implemented.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-09 14:18:24 -05:00
Kevin O'Connor
60a4bda9d4 basecmd: Use oid_ prefix for the oid manipulation functions
Consistently use an "oid_" prefix on the oid functions - this makes
them similar to other functions with a common prefix.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-09 13:49:03 -05:00
Kevin O'Connor
d5fc594317 mcu: Support inverted PWM pins
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-09 00:46:53 -05:00
Kevin O'Connor
64407dc5d2 klippy: Support FIRMWARE_RESTART command
Add initial support for micro-controller resets via the Arduino reset
mechanism.  Also, automatically attempt a firmware restart if the
printer CRC does not match.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-08 23:02:31 -05:00
Kevin O'Connor
b0329465ec serialhdl: Make sure to close the serial port on disconnect()
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-08 23:02:31 -05:00
Kevin O'Connor
0f70b420f2 mcu: Improve error messages on failure to config printer
Don't report a CRC mismatch if a shutdown or other failure occurs
during config - instead report the appropriate details.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-08 21:44:17 -05:00
Kevin O'Connor
21c4dea0e6 serialhdl: Detect timeout in SerialReader.send_with_response()
Raise an error if the response is never received.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-08 21:25:54 -05:00
Kevin O'Connor
bcaf818c0e fan: Default to using software PWM
Not all hardware has PWM support and there is no compelling reason to
use hardware PWM for fans.  Change the default to use software PWM.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-08 20:23:09 -05:00
Kevin O'Connor
37bac916e7 basecmd: Generalize the "move queue" runtime storage
Detect the maximum size of each "move queue" item during the
configuration phase instead of using the stepper move struct.  This
allows the stepper code to be contained entirely in stepper.c and it
allows for future run time allocations from other types of objects.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-08 13:37:51 -05:00
Kevin O'Connor
affdbbf9ca sam3x8e: Fix typo in gpio_in_setup() shutdown message
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-08 13:17:45 -05:00
Kevin O'Connor
4fcf0ff2ac docs: Fix typo in description of fan pin.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-07 19:13:37 -05:00
Kevin O'Connor
c19af4fb2b serialhdl: Load the mcu's 64bit clock at start of connection
Store a full 64bit uptime in the mcu and query it at the start of each
connection.  This ensures the host's 64bit clock is always in synch
with the mcu's clock.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-03 22:02:27 -05:00
Kevin O'Connor
f53897758d heater: Support max_power setting for heaters
Change the mcu PWM value from an integer (0-255) to a float (0. - 1.).
Add support for limiting the maximum power (as measured over a
sufficiently long duration) to a particular heater.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-03 20:00:16 -05:00
Kevin O'Connor
54002c4391 extruder: Pressure advance lookahead time should start after decel
The pressure advance lookahead time should start after any full
deceleration moves.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-03-03 14:20:41 -05:00
Kevin O'Connor
6a53eaefc0 extruder: Allow configuration of pressure advance lookahead time
Instead of defaulting the pressure advance lookahead time to be the
same as the pressure_advance variable, allow it to be configured.
Default the new config setting (pressure_advance_lookahead_time) to
10ms.

Also, make the setting more accurate if a future move is accelerating
in the middle of the lookahead window.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-22 15:20:22 -05:00
Kevin O'Connor
4bc114336c delta: Simplify maximum stepper velocity and accel checks
Simplify the mechanism for limiting stepper speed (introduced in
commit bdfdf7ef) - split the extreme end of the build envelope into
two zones and use the same speeds for all moves that traverse any part
of one of those zones.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-21 11:18:56 -05:00
Kevin O'Connor
47f1d377f5 heater: Enforce min/max_temp in heater.set_temp()
Raise an error if the user requests a temperate outside the configured
min/max_temp range.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-21 10:48:42 -05:00
Kevin O'Connor
566699f68a toolhead: Fix error in lookahead logic
Commit c24b7a7e reworked the way lookahead was done and it introduced
a bug when a full acceleration move is immiedietly followed by a full
deceleration move.  In that situation, depending on when the lookahead
queue was flushed, it was possible to call move.move() without calling
move.set_junction().  This resulted in a "Move instance has no
attribute 'accel_t'" internal error.

Simplify and fix the logic for checking full accel moves followed by
full decel moves.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-20 12:50:12 -05:00
Kevin O'Connor
29ba92a551 delta: Use position_endstop for position_max
There's no reason for the user to specify position_max - it can be
inferred on deltas from the endstop positions.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-19 11:00:46 -05:00
Kevin O'Connor
38e9484f9f armcm_irq: Move ARM Cortex-M irq handling to new file
The irq handling in sam3x8e isn't specific to the sam3x8e proccessor -
it's generic for all armcm type machines.  So, move the definitions
into a new file generic/armcm-irq.c

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-19 11:00:46 -05:00
Kevin O'Connor
fec12030a9 sam3x8e/timer: Be careful of races in timer_set_next()
It's possible for sched_del_timer() to be called on a timer that fires
just after sched_del_timer disables irqs but before the next timer is
scheduled.  In this case be sure to clear the irq pending status flag
after scheduling the next timer so that a delayed irq doesn't cause
the wrong timer to be run.  For the same reason, make sure to check
the irq pending status flag at the start of the timer irq.

Also, as a safety check, make sure timer_set_next() isn't called from
within the timer irq dispatch loop.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-14 22:15:51 -05:00
Kevin O'Connor
bdfdf7ef55 delta: Cap maximum stepper velocity and acceleration
Some XY moves at the extreme end of the build envelope could cause
excessive axis stepper movement.  Check for any moves that could
possibly result in a stepper movement of more than 3 times the XY
movement and cap the move's acceleration and speed.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-13 21:47:10 -05:00
Kevin O'Connor
9f65ae72c3 delta: Rework boundary checks
Calculate and store the maximum xy2 value for the given z level each
time the head moves to a new z level.  This simplifies the boundary
check for common XY moves.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-13 17:51:13 -05:00
Kevin O'Connor
3434ea540c klippy: Log the type of cpu the host is running on
Report in the log the host CPU type and count.  This helps distinguish
between different rpi versions when debugging the log from a problem
report.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-12 19:14:26 -05:00
Kevin O'Connor
29131c873a gcode: Attempt to shutdown heaters and fans prior to a RESTART
If the user requests a restart and the machine appears to be otherwise
functioning normally, then attempt to stop the heaters and fans prior
to restarting the host.  This prevents the firmware from going into a
shutdown state when the heater is on and the host restarts.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-12 18:48:21 -05:00
Kevin O'Connor
ab1eb70d1c toolhead: Rework lookahead flush to be more stable during high cpu
Change the lookahead queue so that it attempts to buffer at least
buffer_time_high amount of moves when first starting a print.  This
helps ensure the buffer is normally always full.

If the buffer falls below buffer_time_low then it is either due to the
end of a print or because octoprint/klippy is unable to keep up.
Change the code so that in this case the lookahead queue will attempt
to gather buffer_time_high amount of moves before restarting movement.

Update the default buffer_time_low to 1 second and buffer_time_high to
2 seconds.  With the above changes a smaller buffer_time_high and a
larger buffer_time_low are more practical.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-12 17:20:40 -05:00
Kevin O'Connor
71256f9456 toolhead: Flush lookahead buffer by time
Use a minimum time window as a heuristic for determining when to try
to lazily flush the lookahead buffer.  In the common case this will
result in more moves processed for each flush and thus reduce the
overall cost of the lookahead processing.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-12 17:20:40 -05:00
Kevin O'Connor
6179839215 toolhead: Separate motor off timer from main flush timer
Move the motor off time checking to its own code.  This simplifies the
main flush handler.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-12 17:20:40 -05:00
Kevin O'Connor
0ca96e543c toolhead: Increase maximum stepper halt velocity
Do a better job of calculating the maximum halt velocity for the
stepper motors.  The maximum cornering velocity is related to both the
maximum acceleration and the junction_deviation, so both should be in
the formula.  Tests show that "math.sqrt(8. * self.junction_deviation
* self.max_accel)" very closely fits the maximum on cartesian robots.

This fixes potential "no next step" shutdowns that could occur on
some print moves.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-12 17:20:40 -05:00
Kevin O'Connor
acb0b8f599 klippy: Fix omission causing gcode dump to not function
Fix bug that broke the gcode command dump after a shutdown.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-12 17:19:58 -05:00
Kevin O'Connor
20d0936fa2 reactor: Use the system monotonic clock instead of the normal system clock
The normal system clock can have sudden jumps if the system clock is
changed.  Use the system monotonic clock to avoid these sudden changes
in time.

It appears the Raspbian OS (which is used by OctoPi) is setup to
update the system clock upon network connectivity.  This could cause
sudden system clock changes which could lead to Klippy processing
errors.  Using the monotonic clock eliminates these issues.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-06 13:31:34 -05:00
Kevin O'Connor
c24b7a7ef9 toolhead: Introduce "smoothed" acceleration during lookahead
Update the lookahead code to track both normal toolhead acceleration
as well as a pseudo acceleration to the point of deceleration.  This
reduces the top speed of small zig-zag moves and it reduces printer
vibration during these moves.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-06 12:17:50 -05:00
Kevin O'Connor
074495a13a toolhead: Remove unneeded forward pass in MoveQueue.flush()
Simplify the code now that the extruder lookahead is separate from the
main lookahead code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-06 12:17:50 -05:00
Kevin O'Connor
e14d86d8b8 toolhead: Remove the do_calc_junction flag
It is not necessary to track the do_calc_junction flag as it can just
as easily be determined at the top of the calc_junction() method.
This simplifies the code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-06 12:17:50 -05:00
Kevin O'Connor
528c29c01c extruder: Do extruder lookahead based on time instead of cornering
When calculating the extruder lookahead, determine how far to
lookahead by the amount of elapsed time each move takes.  This makes
the extruder lookahead code more flexible as it is no longer limited
to the next immediate cornering moves.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-06 12:17:50 -05:00
Kevin O'Connor
1bb7a22115 extruder: Move extruder specific lookahead into extruder class
Instead of calculating min/max_corner_v in the toolhead class,
calculate it in the extruder class.  This keeps the extruder specific
code together.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-06 12:17:50 -05:00
Kevin O'Connor
19ed67331d stepcompress: Propagate errors back to python code
Propagate error codes back to the python code and raise an exception
on an error.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-06 12:17:50 -05:00
Kevin O'Connor
667b72870f gcode: Exit on an unhandled exception when reading from a file
When testing via a gcode input file, it's easier to debug problems if
the program exits upon the first exception.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-06 12:17:50 -05:00
Kevin O'Connor
4194ebf9df graphstats: Display host buffer stats in graph
Prune host buffer stats near the start and end of the print.  Graph
the remaining buffer stats.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-02 10:46:48 -05:00
Kevin O'Connor
5beceaae5c io.h: read/write[bwl] should use barrier
Add barrier() calls to low-level read/write io calls so that their
callers don't need to.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-02-02 10:46:42 -05:00
Kevin O'Connor
9c1bf1387c toolhead: Make sure max_corner_v2 is fully calculated on a lazy flush
Make sure max_corner_v2 is fully calculated before proactively
flushing moves from the lookahead queue.  Without this, some moves
would do unnecessary pressure advance during cornering.

Also, handle the min/max_corner_v2 calculations correctly in the rare
case where a move that does only acceleration is immediately followed
by a move that does only deceleration.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-16 15:32:35 -05:00
Kevin O'Connor
fc6a31eac8 toolhead: Change variables to use suffix "_v2" instead of prefix "junction_"
The junction speeds are tracked in velocity squared - introduce the
common suffix "_v2" to track that instead of using a prefix of
"junction_".

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-16 15:32:35 -05:00
Kevin O'Connor
064e8bdd84 toolhead: Clear do_calc_junction if using non-default accel
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-14 12:48:16 -05:00
Kevin O'Connor
262ccbcf30 serial: Be careful with comparison of transmit_max to transmit_pos
There is a small possibility that a shutdown could occur between
clearing transmit_max and clearing transmit_pos - so make sure to
handle the case where transmit_pos > transmit_max.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-14 12:11:30 -05:00
Kevin O'Connor
7567885115 sched: Minor change - remove unneeded header files
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-14 11:32:27 -05:00
Kevin O'Connor
ed715ec437 command: No need to disable irqs in sendf reentrant check
As long as the code is careful when writing the in_sendf variable it
should be safe to update it without having to disable irqs.

Also, make sure in_sendf is cleared on shutdown.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-14 11:32:27 -05:00
Kevin O'Connor
9a44a20a9d command: Check for reentrant calls to sendf()
Allow sendf() to be called from irq and timer context - check for the
case where sendf() is called while already in sendf() and simply
discard those messages.  This makes it safe to use output() debugging
calls even in irq and timer context.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-13 12:10:00 -05:00
Kevin O'Connor
f335045273 heater: Resend PWM values even if last value was zero
Continue to resend the pwm value even if the last value was zero -
this extends the debugging info.

Also, add the target temperature to the pwm debugging.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-12 15:13:41 -05:00
Kevin O'Connor
4ea091339e heater: Only create a soft PWM object for PID heaters
The "watermark" style heater only needs a digital_out pin - not a
software PWM pin.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-10 18:36:43 -05:00
Kevin O'Connor
8378b7345b toolhead: Change cornering_min/max variable name to junction_corner_min/max
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-10 18:35:52 -05:00
Kevin O'Connor
4a71c7a2bd heater: Report last temperature in PWM debugging
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-10 12:36:51 -05:00
Kevin O'Connor
b2885a53cb klippy: Increase precision of reported statistics timestamp
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-10 12:35:30 -05:00
Kevin O'Connor
46b6b4037d reactor: Reload eventtime if a greenlet is reactivated
Fix a bug causing timers to be delayed when pause() is called from a
fd event.  The eventtime needs to be reloaded when an old greenlet is
reactivated.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-10 11:19:39 -05:00
Kevin O'Connor
93d3a6e1d1 klippy: Warn the user on common errors due to old firmware
Check for msgproto.error and warn the user about version firmware
version mismatch.  Raise msgproto.error when extracting firmware
constants.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-10 00:13:28 -05:00
Kevin O'Connor
eebaeeff96 util: Use path of script instead of current directory for git version
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-09 23:33:23 -05:00
Kevin O'Connor
3a7a77d49e basecmd: Improve accuracy of stats "sumsq" variable
Use a base of 256 instead of 65536 when calculating the sum of the
square of the clock differences in the stats.  This makes the
calculation more accurate.  Export the new base via DECL_CONSTANT for
the host to access.  Use DIV_ROUND_UP() when adjusting for the base to
ensure no lost ticks.  Do the division after multiplication in the
common case where the time between stats_task() invocations is less
than 64K ticks.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-09 23:08:23 -05:00
Kevin O'Connor
c87c090264 extruder: Calculate sane defaults for extrude only velocity and accel
Instead of requiring the user enter velocity and accel parameters for
extrude only moves, calculate sane defaults from the printer's maximum
velocity and accel.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-03 18:18:30 -05:00
Kevin O'Connor
b26922978a extruder: Do sanity checks on extrusion rates
Add a run-time check to ensure the incoming g-code doesn't have a
ridiculously large e move.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-03 18:17:43 -05:00
Kevin O'Connor
5a5bd2596a extruder: Add nozzle and filament diameter config settings
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-03 18:12:51 -05:00
Kevin O'Connor
38ca051381 config: Update example config files to be more clear on default values
Be more clear on which parameters have defaults and which parameters
must be specified in the config.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-02 13:22:20 -05:00
Kevin O'Connor
91056809dd mcu: Change the default baud rate to 250000
Update the default baud rate in mcu.py to 250000 (as that is the
default in all other places).

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-02 12:22:43 -05:00
Kevin O'Connor
f75430e95f gpio: Fix sam38xe ADC startup check
The status register needs to be inspected, not the enable register.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2017-01-01 22:10:24 -05:00
Kevin O'Connor
8e797e6830 stepcompress: Flush periodically if adding more than 64K steps in a move
It's possible for a printer with very fine resolution to require a
large number of steps for a homing operation.  Instead of storing all
of those steps in memory, periodically flush the queue should more
than 64K steps be present.  This keeps a reasonable limit on the
amount of ram needed to store steps.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-31 13:21:53 -05:00
Kevin O'Connor
73c4be3fd3 docs: Update protocol document with internal VLQ link
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-31 11:30:50 -05:00
Kevin O'Connor
c552ba06b4 serialqueue: Remove serialqueue_flush_ready()
The serialqueue_flush_ready() code was used to flush queue_step
commands during a homing operation.  It's no longer necessary now that
moves during a homing operation use the normal message priority
system.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-30 20:15:05 -05:00
Kevin O'Connor
6bd5f4e44e stepcompress: Using normal message priority system during homing
The endstop homing system requires all queue_step commands be in the
MCU's 'move queue' before endstop checking starts.  Use the normal
message priority system to request that stepper queue_step commands
are received prior to the start of the end_stop_home command.  This
simplifies the code and removes the need for special serial queue
flushing.

This also fixes a bug in homing operations that take longer than 2^31
clock ticks.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-30 20:14:48 -05:00
Kevin O'Connor
6138d18f4b toolhead: Also call reset_print_time() on force_shutdown()
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-28 22:38:29 -05:00
Kevin O'Connor
d028f42e99 mcu: Don't call steppersync_flush if steppersync not created
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-28 22:38:29 -05:00
Kevin O'Connor
860fc3e91d gcode: Add support for M115 command
Support querying the firmware type and version.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-28 22:38:29 -05:00
Kevin O'Connor
2e03d84755 gcode: Add support for M400 command
Add ability to fully stall the input until all moves are complete.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-28 22:38:28 -05:00
Kevin O'Connor
f2b406fc5e toolhead: Don't call into kinematic class on extrude only moves
Add a is_kinematic_move flag to the Move class and clear it on extrude
only moves.  Don't call the kinematic check_move() or move() methods
for extrude only moves.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-28 22:38:28 -05:00
Kevin O'Connor
f46bc0ef04 stepper: Change default max_error from 50us to 25us
Change the default compression error window (max_error) from 50us to
25us - it's common for stepper motor drivers to have 30us for their
"pwm fixed off time" and it would be good for the steps to be
scheduled within that time.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-28 22:38:27 -05:00
Kevin O'Connor
800d53db6a stepcompress: Rework addfactor integer overflow check
Revert 4a16053c and avoid integer overflows in the addfactor
calculation by exiting the loop early if count > 0x200.  This provides
stronger protection against overflows.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-26 12:47:17 -05:00
Kevin O'Connor
a9444d3399 mcu: Log the MCU configuration during connect phase
Log the constants reported by the MCU and log the number of move items
allocated after configuration.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-24 12:33:56 -05:00
Kevin O'Connor
4a16053c00 stepcompress: Fix integer overflow leading to infinite loop
Commit a217c0f3 changed the way the "addfactor" was calculated.
Unfortunately, it was possible for the updated method to cause an
integer overflow and have a negative addfactor.  Fix this by
explicitly casting the addfactor calculation to uint32_t.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-24 12:02:37 -05:00
Kevin O'Connor
d0c61f0f76 klippy: Log the contents of the config file at startup
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-24 10:18:41 -05:00
Kevin O'Connor
451ffd567d klippy: Log the host software git version at startup
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-24 10:17:48 -05:00
Kevin O'Connor
f3a49604f1 stepcompress: Increase check on max count to 10000000
Some motors have very small step distances and they can generate over
a million steps during a homing operation.  Increase the maximum count
to ten million to avoid triggering the internal sanity check.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-23 23:13:35 -05:00
Kevin O'Connor
3576dd6e87 docs: Note version 0.3.0 release
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-23 19:10:09 -05:00
Kevin O'Connor
3b668c9baf docs: Add Releases page with history of releases
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-23 18:28:42 -05:00
Kevin O'Connor
618fe0e6fb sam3x8e: Add support for ADC pins
Support analog-to-digital inputs.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-23 17:06:11 -05:00
Kevin O'Connor
872b08601a mcu: Obtain the maximum adc value from the firmware
Don't assume the hardware ADC has 10bit resultion - instead have the
firmware define a constant and read that constant in the host.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-23 17:06:10 -05:00
Kevin O'Connor
fe95ea221b build: Define DECL_CONSTANT mechanism for defining exported constants
Add a DECL_CONSTANT macro to allow the firmware to define constants
that are to be exported to the host during the "identify" phase.  This
replaces the existing hardcoded mechanism of scanning the Kconfig
header file for certain constants.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-23 17:06:10 -05:00
Kevin O'Connor
4e8674d5df build: Disable gcc's use-linker-plugin option
On GCC v6 the -fwhole-program option does not take effect when
-fuse-linker-plugin is also in effect. The -fuse-linker-plugin option
does not optimize as well as -fwhole-program, so explicitly disable
the linker plugin via -fno-use-linker-plugin.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-22 22:48:14 -05:00
Kevin O'Connor
9894348e12 docs: Add an example to the description of the message block contents
Use a more real-world example to improve the description of message
block contents. Make it more clear that the data dictionary contains
and utilizes the full command descriptions.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-22 13:38:45 -05:00
Kevin O'Connor
189ac86b06 docs: Update protocol document to highlight its "compression" system
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-21 15:10:25 -05:00
Kevin O'Connor
6f3bbafbbd docs: Minor wording change to protocol document
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-21 14:06:44 -05:00
Kevin O'Connor
3a478adeaa docs: Minor updates to protocol document
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-21 13:54:45 -05:00
Kevin O'Connor
29aa6ef6c7 docs: Update installation document
Various installation updates.  Recommend upgrade to OctoPrint v1.3.0.
Recommend configuring OctoPrint to not disconnect on error.  Note
quirk with needing to reload page if "/tmp/printer" not in list of
serial connections.  Add brief documentation on use of extended
commands and checking for errors.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-21 12:01:39 -05:00
Kevin O'Connor
219796ef4e gcode: Add a "STATUS" command
Add a status command that will report the current printer status.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-21 11:35:00 -05:00
Kevin O'Connor
4f087c331c klippy: Update config error message - use "RESTART" when ready to continue
It is possible to restart the host software with a RESTART command
after manually resetting the micro-controller.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-21 11:16:06 -05:00
Kevin O'Connor
18456f71f8 docs: Add a features document
Add a document describing some high-level features in Klipper.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-20 22:31:46 -05:00
Kevin O'Connor
1d841eeb87 stepcompress: Prefer greater interval if all else equal
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-19 11:20:39 -05:00
Kevin O'Connor
19d1f83d97 stepcompress: Move check for add=0 sequences out of loop
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-19 11:20:38 -05:00
Kevin O'Connor
6efadf44d0 stepcompress: Favor higher add values when bisecting
Instead of splitting the available "add range" in half, try for add
values closer to the higher end of the range.  This heuristic seems to
result in better choices.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-19 11:20:38 -05:00
Kevin O'Connor
e4c4a4628b stepcompress: Use inclusive range on min/maxadd
Change the min/maxadd variables to use an inclusive range instead of
exclusive.  This better matches min/maxinterval.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-19 11:20:38 -05:00
Kevin O'Connor
a217c0f394 stepcompress: Be consistent with "point" vs "nextpoint"
Make it clear which variables refer to the best verified point found
so far, and which variables deal with the next (not yet verified)
point.

Also, remove checked_count as bestcount serves the same purpose.

Also, allow minmax_point to be inlined.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-19 11:20:38 -05:00
Kevin O'Connor
1dbd11446c stepcompress: Don't warn on multi-step interval=0 sequences
It is possible to get a valid multi-step sequence with an interval of
zero if the add is non-zero.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-14 11:03:16 -05:00
Kevin O'Connor
74fa8a3907 serialhdl: Clear "hupcl" bit from serial port
The arduino style serial port interfaces can reset the MCU when the
serial port is opened.  Clearing the HUPCL flag makes this less
likely.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-09 19:07:03 -05:00
Kevin O'Connor
cad1e0b985 docs: Recommend latest version of pyserial in installation instructions
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-09 18:59:36 -05:00
Kevin O'Connor
b099851a8b gcode: Increase initial speed
If a speed is never specified then default to 25mm/s (up from 1 mm/s).
If a user accidentally issues a move without setting the speed, the
default speed shouldn't be so slow that it takes minutes to finish the
move.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-09 17:28:09 -05:00
Kevin O'Connor
f25ead109c gcode: Handle M112 emergency stop command
Also try to support the command if it is sent out of order.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-09 17:09:51 -05:00
Kevin O'Connor
edd7dfe1c8 gcode: Rework toolhead stalling to use greenlets
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-09 17:09:51 -05:00
Kevin O'Connor
89f5452ddb gcode: Rework homing to use greenlets
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-09 17:09:51 -05:00
Kevin O'Connor
a6de1db94d gcode: Rework endstop query to use greenlets
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-09 17:09:51 -05:00
Kevin O'Connor
ed9d7e4fae gcode: Convert wait for temp to use greenlets
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-08 18:15:11 -05:00
Kevin O'Connor
e169f70bfb gcode: Convert busy handler from timer to greenlet
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-08 18:15:11 -05:00
Kevin O'Connor
35428f2e04 cartesian: Make it clear which methods of CartKinematics are internal
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-08 18:14:46 -05:00
Kevin O'Connor
0718a1bd1f delta: Make it clear which methods of DeltaKinematics are internal
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-08 18:13:34 -05:00
Kevin O'Connor
83f7d702e7 stepcompress: Encourage add=0 in compress_bisect_add()
Only use a non-zero 'add' if it actually extends the number of steps
the command covers.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-06 19:01:00 -05:00
Kevin O'Connor
12d4888321 graphstats: Updates for recent stats changes
Update the graphstats helper script to account for recent changes in
the statistics output.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-06 11:10:52 -05:00
Kevin O'Connor
4565a73e91 stepcompress: Optimize push_delta_const() for common XY or Z only moves
Most moves are on the XY plane - avoid a few multiplications in the
inner loop in this case.  When there is a Z move, it is almost always
entirely a Z move - avoid the sqrt() call in the inner loop in this
case.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-05 14:40:29 -05:00
Kevin O'Connor
9c932ad514 delta: Rework delta math to avoid using inv_movexy_r
Taking the inverse of the XY move distance can lead to extremely large
values when the XY distance is very small.  This can lead to
saturation of the double precision variables and incorrect results.

Rework the delta kinematic math to avoid using this inverse.  Pass the
closestxy_d value directly to the C functions so that the C code can
calculate its intermediate constants.

After this change the move_z special case is no longer necessary as
the regular delta functions now work with movexy_r=0 and movez_r=1.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-05 14:36:02 -05:00
Kevin O'Connor
5458f3cbd2 delta: Make sure homing distance is large enough to hit the endstop
The head may be far away from an axis at the start of a home, and that
axis must then traverse more than just the distance from zero height
to the endstop position.  Add in additional distance to account for
this.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-05 14:06:38 -05:00
Kevin O'Connor
611e1d239b config: Update avrsim.cfg with recent config file changes
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-02 16:21:23 -05:00
Kevin O'Connor
d2abbd8f5d extruder: Fix retract
Commit 7554c7f6 broke retract moves.  Fix by making sure extrude_r is
always a positive number.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-01 18:17:54 -05:00
Kevin O'Connor
00b40b720f klippy: stats() method must check that mcu and toolhead classes exist
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-01 18:17:54 -05:00
Kevin O'Connor
71b4923208 delta: Support limiting the maximum velocity of z moves
On a delta printer, z moves require the mcu to support the greatest
number of steps per second.  However, z moves are rare, so it makes
sense to limit the velocity of z moves separately from the velocity of
normal xy moves.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-01 18:17:54 -05:00
Kevin O'Connor
c49d3fdb17 toolhead: Specify maximum acceleration and velocity in toolhead class
Change the config file so the maximum accel and velocity are specified
in the "printer" section instead of the individual "stepper" sections.
The underlying code limits the velocity and accel of the toolhead
relative to the print object, so it makes sense to configure the
system that was as well.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-01 18:17:54 -05:00
Kevin O'Connor
fcaf359e89 stepstats: Update stepstats script with change in dir_pin meaning
Commit afecf7ce inverted the direction of the direction pin in
queue_step commands - update the stepstats script to conform.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-01 18:16:18 -05:00
Kevin O'Connor
9a31c068c4 klippy: Fix typo causing missing stats on 'exit_eof' case
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-01 10:55:04 -05:00
Kevin O'Connor
babc9e7a1e docs: Minor updates to wording of some documents
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-01 10:21:36 -05:00
Kevin O'Connor
d2ecc9d80c gcode: Add support for CLEAR_SHUTDOWN command
Add ability to clear the MCU shutdown flag from the console.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-12-01 00:21:20 -05:00
Kevin O'Connor
fbd7cc243b klippy: Add ability to restart the host software
Add a "restart" gcode command that will cause the host "klippy"
software to reload its config and restart.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-30 23:53:03 -05:00
Kevin O'Connor
a6055ce069 gcode: Support parsing of "extended" gcode commands
Support human readable commands (eg, "help").  Add a "help" command to
list these extended commands.

Also, add support for declaring command aliases, command help, and
command availability next to the handlers themselves.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-30 23:00:29 -05:00
Kevin O'Connor
35719e665c delta: Fix delta kinematics startup
Commit 1e1364c3 moved the storage of the stepper position to the
mcu_stepper class.  The initializing of that position needs to be
pushed back until after the mcu_stepper class is instantiated.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-30 21:24:03 -05:00
Kevin O'Connor
bc80ed4e88 mcu: Detect if the communication channel to the firmware is lost
Detect a comms loss and report it to the user.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-30 21:20:09 -05:00
Kevin O'Connor
5ebe8ce025 gcode: Don't dump the message log directly from set_printer_ready()
The set_printer_ready() method can be called from a background thread.
Have the main Printer class call a new dump_debug() method in the main
thread on a shutdown event.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-30 21:20:09 -05:00
Kevin O'Connor
17dcb42752 klippy: Validate that options in the config file exist
Check that all options specified in the config file are valid.  This
catches possible typos and spelling errors in variable names that have
a default.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-30 21:20:09 -05:00
Kevin O'Connor
2f97b2d7c2 klippy: Add ConfigWrapper.getchoice method
Add helper function that ensures a config option is one of several
choices.  This helps ensure that a proper error is raised if an
invalid choice is made.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-30 21:19:44 -05:00
Kevin O'Connor
57244de37d klippy: Throw an exception if any required config parameter is missing
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-30 21:19:44 -05:00
Kevin O'Connor
3806ed882a mcu: Raise a config error on an invalid pin name in the config file
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-30 21:19:44 -05:00
Kevin O'Connor
ce7e7c4048 klippy: Report an error if the config file does not exist
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-30 21:19:44 -05:00
Kevin O'Connor
524e0290bc klippy: Improve error reporting during connect
Catch exceptions during the connect phase and report them via the
gcode interface to the user.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-30 21:19:44 -05:00
Kevin O'Connor
dbdf1e137e gcode: Support reading from gcode input before mcu is ready
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-30 21:19:43 -05:00
Kevin O'Connor
6ebb1a68cb klippy: separate initial config file load into load_config() method
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-30 21:19:43 -05:00
Kevin O'Connor
7e7e607e3f klippy: Create the /tmp/printer pseudo tty before opening config file
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-30 21:19:43 -05:00
Kevin O'Connor
4eb21a71ae klippy: Defer calling mcu.connect_file() to connect() method
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-30 21:19:43 -05:00
Kevin O'Connor
4f07ee4d92 pyhelper: Add ability to route error messages to python logging
Instead of writing error messages to stderr, route them into the
python code and use the standard python logging system.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-30 21:19:43 -05:00
Kevin O'Connor
b14db404b5 pyhelper: Move helper functions from serialqueue.c to new file
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-30 13:33:16 -05:00
Kevin O'Connor
7cb71df02c mcu: Be careful to free memory allocated in C code
Free steppersync, stepcompress, and commandqueue objects.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-30 13:33:16 -05:00
Kevin O'Connor
55fc11ff02 serialhdl: Retry opening of serial port
Continually retry to open the serial port.  This helps with connecting
to some micro-controllers.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-29 21:58:48 -05:00
Kevin O'Connor
0d43d269ed serialhdl: Fully deallocate serialqueue on disconnect
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-29 21:58:48 -05:00
Kevin O'Connor
a0829c63de serialhdl: Make SerialReader.send_with_response() blocking
Use the greenlet mechanism to wait for the response directly in the
send_with_response() method.  This simplifies the calling code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-29 21:58:45 -05:00
Kevin O'Connor
535c7b99b4 serialhdl: Make SerialReader.connect() blocking
Use the greenlet mechanism to wait for the connection to come up in
the serial connect() method.  This simplifies the calling code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-29 21:57:49 -05:00
Kevin O'Connor
5d805ba550 klippy: Run the MCU connect code within the reactor
Setup the reactor and run the MCU connection code as a timer within
the reactor.  The connection code will make use of reactor greenlets
so that it can wait for events during the connection phase.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-29 21:54:45 -05:00
Kevin O'Connor
bafe796eeb reactor: Add support for greenlets
Add support for greenlets - a mechanism for tasks that can pause while
still allowing regular reactor events to occur.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-29 21:54:45 -05:00
Kevin O'Connor
ceb60ffcc6 mcu: Rename output_file_mode variable to is_fileoutput
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-29 21:54:40 -05:00
Kevin O'Connor
72c4f353e6 serialqueue: Kick the background thread from serialqueue_exit
Wake the background thread up when exiting - as this makes the exit
complete faster (and have more predictable timing).

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-29 18:49:12 -05:00
Kevin O'Connor
4d6830a373 serialqueue: Fix possible memory leak in serialqueue_extract_old()
Make sure to free all messages even if the requested size is smaller
than the number of messages.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-29 18:49:12 -05:00
Kevin O'Connor
f547cab710 klippy: No need to define __str__ and __init__ methods on exception classes
The base Exception class already defines these methods.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-29 18:49:12 -05:00
Kevin O'Connor
7835f50722 klippy: Eliminate write_dictionary command line option
The feature is not necessary and it will be difficult to maintain
in the future.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-29 18:21:57 -05:00
Kevin O'Connor
d161d66741 mcu: Handle adc initialization entirely in mcu code
Don't expose the ADC initialization to the gcode and heater code -
instead, register a callback within the MCU_adc class and call it
directly from the MCU class after configuration completes.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-29 18:21:56 -05:00
Kevin O'Connor
9755182adf homing: Check homing distance to verify endstop trigger after retract
Instead of checking the endstop trigger directly after a retract move,
verify some distance is traveled during the following homing
operation.  This reduces the amount of synchronization between mcu and
host during homing.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-28 11:23:26 -05:00
Kevin O'Connor
a5637bb9d4 mcu: Track the stepper position in the MCU in the MCU_stepper class
Support tracking of both the commanded_position and the mcu_position
in the MCU_stepper class.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-28 11:22:01 -05:00
Kevin O'Connor
1e1364c3d4 mcu: Store the stepper position in the mcu_stepper class
Move the storage of the stepper location from the kinematic classes to
the low-level mcu_stepper class.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-19 11:34:42 -05:00
Kevin O'Connor
7cf914537b stepper: Raise an EndstopError if invalid phase found during homing
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-18 14:39:48 -05:00
Kevin O'Connor
ab1972d1cf homing: Verify the endstops are no longer triggered after retract move
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-18 14:17:53 -05:00
Kevin O'Connor
e0aa067cc9 homing: Check for timeout during homing operation
Should a homing move complete without hitting the endstop, then
disable motors, disable the endstop checking, and report the error to
the user.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-18 14:17:53 -05:00
Kevin O'Connor
4f30dce64f homing: Add EndstopMoveError wrapper around EndstopError
Allow an EndstopError to be raised without a destination position.
Introduce EndstopMoveError wrapper so that current callers can
continue to pass in a move destination.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-18 14:17:53 -05:00
Kevin O'Connor
2b5b899d35 homing: Direct stepper phase detection from kinematic classes
Change the scheduling of the final homed position (which takes into
account the stepper phases) so that it is scheduled from the kinematic
classes instead of from the toolhead class.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-18 14:04:10 -05:00
Kevin O'Connor
781cf608d7 homing: Create Homing class from gcode
Create the Homing class in the gcode handler instead of in the
kinematic classes.  This will make it easier to pass error messages
back to the user.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-18 14:04:09 -05:00
Kevin O'Connor
9e1059afb4 homing: Create QueryEndstops class from gcode
Create the QueryEndstops in the gcode handler instead of in the
kinematic classes.  This simplifies the gcode handler as it can
directly register its response callback.

Also, store the stepper name in the stepper class.  Also, propagate
the print_time of the query request to the mcu_endstop class.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-18 14:04:09 -05:00
Kevin O'Connor
7ef8c0442a mcu: Remove support for DummyMCU class
It's easier to test with the file output mechanism and the DummyMCU
code has grown stale.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-16 12:09:26 -05:00
Kevin O'Connor
6ab269ceb7 stepcompress: Don't bother loop unrolling in push_sqrt()
It's not necessary to have two loops - checking if factor is greater
than zero in the loop is fine.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-14 15:36:11 -05:00
Kevin O'Connor
fd7cb99f47 stepcompress: Optimize safe_sqrt() code
Optimize the code by putting the uncommon case out-of-line.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-14 15:12:53 -05:00
Kevin O'Connor
5a1ec817d4 stepper: Check if the motor needs to be enabled in the kinematic classes
Check for motor enable in the kinematic classes so it doesn't need to
be checked on every move.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-14 13:40:35 -05:00
Kevin O'Connor
9ad8153d33 stepper: Reset the next step time on a stepper stop
Automatically reset the next step time to zero on a stepper_stop()
call.  This makes the host code simpler as it no longer needs to
schedule an explicit reset_step_clock command on the step after a
homing operation.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-14 13:10:14 -05:00
Kevin O'Connor
941427554a delta: Initial support for linear delta kinematics
This adds support for delta based robots.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-14 12:35:36 -05:00
Kevin O'Connor
7554c7f694 stepcompress: Do all step rounding in C code
Commits f0cefebf and 8f331f08 changed the way the code determined what
steps to take on fractional steps.  Unfortunately, it was possible in
some situations for the C code to round differently from the python
code which could result in warnings and lost steps.

Change the code so that all fractional step handling is done in the C
code.  Implementing the step rounding logic in one location avoids any
conflicts.

In order to efficiently handle the step rounding in the C code, the C
code has also been extended to directly send the "set_next_step_dir"
command.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-13 18:29:45 -05:00
Kevin O'Connor
79da35d023 stepcompress: Minor code movement
Move flush() and check_expand() code to a new location so that the
stepcompress_push_X() functions can flush.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-12 22:55:27 -05:00
Kevin O'Connor
1dee1ba64e queuelogger: Add support for background log writing
Writing to the debug log can cause an unbounded delay due to disk IO.
This is particularly so on embedded machines such as the Raspberry Pi
that run on SD cards.  These log writing delays can cause problems for
the main processing threads.

The new "queuelogger" code forwards all the main thread log messages
to a queue, and a background thread writes the log messages from the
queue to the destination file.  This eliminates the IO delay from the
main threads.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-12 22:53:43 -05:00
Kevin O'Connor
afecf7ce36 stepper: Default to a high direction pin meaning positive direction
Invert the default meaning of the stepper direction pin.  Instead of
treating a low value as position motion, treat a high value as
positive motion.  This matches what other firmwares do, and it matches
what common stepper motor drivers document.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-08 10:39:32 -05:00
Kevin O'Connor
5e6127869a mcu: Do not invert the direction of pullup pins by default
A pullup setting on an input pin (ie, '^') should enable the hardware
pullup resistor, but it should not invert the trigger level (ie, it
should remain trigger on high).  Those that need to change the trigger
level (ie, trigger on low) must now do that explicitly (ie, '^!').
This makes the code match what other firmwares do.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-08 09:29:38 -05:00
Kevin O'Connor
3b5b895a10 heater: Do not require target temperature be above min_extrude_temp
Only disable the extruder if the last measured temperature is below
the minimum extrude temperature setting.  Verifying the target
temperature is not necessary, and it can incorrectly prevent some
valid moves.  It's not uncommon for scripts to retract filament
immiedietly after setting the extruder temperature to zero.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-08 09:22:43 -05:00
Kevin O'Connor
345fc41482 extruder: Don't do pressure advance on velocity changes due to cornering
Due to the lookahead, small changes in the direction of the toolhead
cause minor changes in toolhead velocity.  These "cornering" velocity
changes cause the current extruder code to trigger pressure advance
and its associated pressure retract.  This causes the extruder to
rapidly "jerk" the filament.

This code change updates the extruder to detect velocity changes due
solely to cornering and avoid pressure advance.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-05 11:06:58 -04:00
Kevin O'Connor
93dd310add extruder: Don't assume start_v matches last end_v in pressure advance
Due to minor differences in the extrude ratio, the last end velocity
of the filament may not exactly match the next move's start velocity
of the filament.  Implement more precise calculations for pressure
advance to take this into account.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-05 11:06:58 -04:00
Kevin O'Connor
a201385008 extruder: Consistently use extrude distance in calculations
Avoid mixing the travel distance of the head (and its associated
velocity and acceleration) with the distance the filament moves.
Instead, use the filament travel distance.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-05 11:04:50 -04:00
Kevin O'Connor
9d7aa1e155 toolhead: Support calculation of cornering minimum and maximum
Calculate the next "cornering" minimum and maximum for each move.  The
"cornering minimum" is the lowest speed the head will reach
immediately after this move (with no interleaving acceleration or
cruising).  The "cornering maximum" is the maximum speed the head will
reach after the cornering minimum (with no interleaving deceleration
or cruising).

These cornering calculations will be helpful in the extruder "pressure
advance" code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-05 10:59:36 -04:00
Kevin O'Connor
6285cc6f66 toolhead: Simplify calculation of junction_cruise
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-05 10:59:36 -04:00
Kevin O'Connor
8e165fecc0 toolhead: Calculate maximum junction start when adding moves
Take into account the maximum possible start speed of a move when
calculating junction_start_max.  This simplifies the lookahead logic.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-05 10:56:47 -04:00
Kevin O'Connor
7c8addc5c5 gpio: Merge gpio_adc_sample_time() into gpio_adc_sample()
Return the number of clock ticks to wait directly from
gpio_adc_sample().  This simplifies the ADC interface.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-02 17:36:43 -04:00
Kevin O'Connor
5419c456ac docs: Add information on the "move queue" to Firmware_Commands
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-02 13:22:35 -04:00
Kevin O'Connor
2b7ab290b8 mcu: Remove python checks for stepcompress integer overflow
Now that the C code checks for overflow, it is no longer necessary for
the python code to check.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-02 13:22:35 -04:00
Kevin O'Connor
508a934d62 stepcompress: Do 32bit integer overflow checks internally in C code
Update the stepcompress C code to check for integer overflow so that
the python code does not need to.  The new checks also handle the
possibility of a single move lasting long enough to cause an overflow.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-02 13:22:35 -04:00
Kevin O'Connor
8025921fc8 stepcompress: Invert the meaning of the min_clock flag
Use a non-zero qm->min_clock value to indicate that the command uses
the move queue and to also store the clock of when that move queue
item will be released.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-02 10:12:26 -04:00
Kevin O'Connor
ff6fef927a stepcompress: Store step times using 64bit integers
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-11-01 19:38:37 -04:00
Kevin O'Connor
77d486f8d2 sam3x8e: Rework timer priority code to use time instead of event count
Rework the timer prioritization code so that is compares against the
current time instead of the number of repeat timers in a given
interrupt.  This makes the code slightly faster and it should provide
better protection against task starvation.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-31 11:48:27 -04:00
Kevin O'Connor
233a90ce8b sam3x8e: Clear all bits of PSR register when clearing IRQ status
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-31 11:47:57 -04:00
Kevin O'Connor
41ef0bd98c stepstats: Add debugging script to calculate stats on stepper movement
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-31 11:15:38 -04:00
Kevin O'Connor
f58d93c0bf graphstats: Add new helper script that generates graphs of MCU load
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-31 11:15:38 -04:00
Kevin O'Connor
8f331f08d2 extruder: Determine start step offset using last commanded position
The existing code calculates the number of steps in a move and then
spreads them out evenly throughout that move.  Change the code so that
step timing is based on where the head is commanded to be relative to
the stepper step locations.  This makes the timing more accurate - in
particular the stepper velocities will be more accurate during
cornering introduced by the lookahead code.  It also results in
slightly smoother stepper motion which results in better step
compression.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-31 11:14:28 -04:00
Kevin O'Connor
f0cefebff7 cartesian.py: Determine start step offset using last commanded position
The existing code calculates the number of steps in a move and then
spreads them out evenly throughout that move.  Change the code so that
step timing is based on where the head is commanded to be relative to
the axis step locations.  This makes the timing more accurate - in
particular the axis velocities will be more accurate during cornering
introduced by the lookahead code.  It also results in slightly
smoother stepper motion which results in better step compression.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-31 11:06:19 -04:00
Kevin O'Connor
2904a0bbac cartesian: Rename step_dist to move_step_d
Don't use step_dist for the "distance along the line of movement per
step" as it's too similar to the stepper.step_dist variable.  Use the
name "move_step_d" instead.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-31 11:05:52 -04:00
Kevin O'Connor
6a96e83ea9 toolhead: Store both the start and end position in the Move class
Store the start position (in addition to the existing end position) in
the Move class.  The start position can be useful to the kinematic
classes.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-25 19:19:29 -04:00
Kevin O'Connor
306db9a851 build: Be sure to also include out/*.d files in Makefile
Not including the out/*.d build files can cause the build to be
incomplete.  In particular, without this fix, if the code is built for
ARM and then configured for AVR, the build can produce a corrupt AVR
binary.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-21 12:00:03 -04:00
Kevin O'Connor
93bd19a8c2 docs: Todo updates
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-19 13:35:49 -04:00
Kevin O'Connor
98ce7dc465 docs: Add Firmware_Commands.md with information on common firmware commands
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-19 13:35:49 -04:00
Kevin O'Connor
9edf60ffc6 docs: Add Protocol.md with information on host / firmware communication
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-19 13:35:49 -04:00
Kevin O'Connor
884cee27eb sched: Improve AVR optimization of reschedule_timer()
Tweak the AVR register pressure optimization in reschedule_timer() to
optimize it further.  This improves the performance of AVR timers when
there are several pending timers.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-19 13:35:48 -04:00
Kevin O'Connor
0f87493487 timer: Rework AVR timer priority code to use time instead of event count
Rework the timer prioritization code so that is compares against the
current time instead of the number of repeat timers in a given
interrupt.  This makes the code slightly faster and it should provide
better protection against task starvation.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-19 13:35:48 -04:00
Kevin O'Connor
8be8cb7a91 serial: Increase AVR serial receive buffer
Increase the size of the serial receive buffer.  With transmit rates
of 250000 baud, it only takes a little over a millisecond to overflow
the existing buffer.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-18 15:01:29 -04:00
Kevin O'Connor
977aabe038 stepper: Return homing offset in steps instead of an absolute position
Rename get_homed_position() to get_homed_offset() and return the
endstop position delta in steps instead of an absolute position
relative to position_endstop.  The conversion to absolute positions
can be dependent on the type of kinematics in use, so is inappropriate
to do in the low level stepper.py code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-13 10:09:56 -04:00
Kevin O'Connor
da7d8dbcac docs: Add todo list to documentation
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-12 10:06:18 -04:00
Kevin O'Connor
3809e4c055 gcode: Reset current position after an endstop error
If the printer is commanded to an invalid location, reset the current
position to the last successfully commanded position.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-11 15:10:19 -04:00
Kevin O'Connor
7f8a94ff48 heater: Make it possible to disable min_extrude_temp for testing
Allow a config file to specify 'min_extrude_temp: 0' to disable the
minimum extrude temperature test.  This makes it easier to perform
testing on the avr simulator.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-11 00:21:30 -04:00
Kevin O'Connor
ee56b14faa mcu: Fix endstop query timeout checking
Commit 0685802c changed the query endstop timeout to use host time
instead of the mcu clock.  However, it is possible for an endstop
homing request to be in the future which makes using the host time
inappropriate.  Revert back to using the mcu clock to determine when
to send an endstop query.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-11 00:21:24 -04:00
Kevin O'Connor
ab54fcd443 stepcompress: Check for small negative numbers on sqrt() calls
It's theoretically possible for floating point truncation to cause a
math formula to return a small negative number instead of 0.  If
sqrt() is called on this small negative number it could cause a
crash.  Check for this case and return 0.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-10 11:39:26 -04:00
Kevin O'Connor
9fa0a62c8a stepcompress: Eliminate possible infinite loop in compress_bisect_add()
Commit 47f30331 converted compress_bisect_add() to use "best reach"
instead of "best add".  However, that change caused
compress_bisect_add() to behave poorly when passed in invalid data
(negative times).  Change the code to better handle invalid data.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-10-10 11:31:56 -04:00
Kevin O'Connor
9faa0fbd25 extruder: Support a minimum extrude temperature
Allow the config file to specify the minimum temperature for the
extruder and check for that temperature prior to moving the extruder
motor.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-09-30 21:36:51 -04:00
Kevin O'Connor
3167e8ddbe extruder: Remove unnecessary getsection('extruder') call
The passed in config object is already pointing to the 'extruder'
section.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-09-30 21:36:51 -04:00
Kevin O'Connor
b53da365a1 cartesian: Enforce endstop min and max boundaries
Verify that each move command is within range of the configured
minimum and maximum for each axis.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-09-30 21:36:51 -04:00
Kevin O'Connor
275b386856 toolhead: Allow kinematics class to verify the move prior to queuing it
Introduce a check_move() method in the extruder and cartesian
kinematic classes.  This allows the lower level classes to verify the
contents of the move prior to queing that move.

The speed and acceleration handling for special Z and extrude only
moves are also moved from the generic toolhead class to the low-level
classes.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-09-30 21:27:46 -04:00
Kevin O'Connor
e9505697fb gcode: Keep a log of incoming gcode data and report it on a shutdown
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-09-30 21:27:46 -04:00
Kevin O'Connor
47f303317b stepcompress: Compress for greatest "reach" instead of greatest "add"
Search for the maximum reachable value instead of the maximum "add".
The maximum reachable value encompasses both the maximum count and a
closest step time to the last requested step time.  This allows for
more "add=0" sequences to be generated which the mcu can optimize for.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-09-24 11:42:06 -04:00
Kevin O'Connor
0685802cb8 homing: Support querying the current status of endstops
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-09-22 11:29:27 -04:00
Kevin O'Connor
c8ff439722 stepper: Disable "no next step" check for some count=1 queue_step commands
It's possible for a "count=1" stepper move immediately after a
set_next_step_dir or reset_step_clock command to be valid and have an
interval less than min_stop_interval.  Make sure this case does not
result in a shutdown.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-09-22 11:15:17 -04:00
Kevin O'Connor
a7b81dc05c toolhead: Force a firmware shutdown on an unhandled exception
Check for unhandled exceptions and force the MCU to shutdown in that
case.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-09-22 11:15:17 -04:00
Kevin O'Connor
0824d32319 cartesian: Minor change to clarify end stop homing direction code
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-09-15 12:20:16 -04:00
Kevin O'Connor
9ff5600421 docs: Clarification of some installation and config steps
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-09-15 12:19:30 -04:00
Kevin O'Connor
94272ed072 heater: Add "ATC Semitec 104GT-2" thermistor definition
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-09-15 12:16:08 -04:00
Kevin O'Connor
7b2f6f89f0 heater: Remove redundant float conversion
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-09-15 12:15:35 -04:00
Kevin O'Connor
06dbc40f53 docs: Describe running Klippy in batch mode for debugging
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-09-10 20:49:25 -04:00
Kevin O'Connor
1bbcb51066 mcu: Write initial config commands when in file output mode
When doing serial file output debugging, write the config commands as
they are often useful to inspect.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-09-10 20:26:52 -04:00
Kevin O'Connor
33a48d926c build: Support creating and storing the data dictionary on each build
Generate the data dictionary in out/klipper.dict on each build.  This
makes it easier to use the dictionary when debugging.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-09-10 20:01:52 -04:00
Kevin O'Connor
c5f50e73c2 mcu: Consistently use mcu_freq variable name (instead of clock_freq)
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-08-25 12:09:37 -04:00
Kevin O'Connor
7276c7085a mcu: Internally store _print_start_time instead of _print_start_clock
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-08-25 12:07:08 -04:00
Kevin O'Connor
e52113a319 mcu: convert stepper, endstop, and digital_out to take mcu_time
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-08-24 16:42:25 -04:00
Kevin O'Connor
11ecac626d mcu: Convert PWM and ADC objects to take mcu_time instead of clock
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-08-24 15:16:02 -04:00
Kevin O'Connor
5a24ab06d8 docs: Update Installation.md - Arduino Due is also supported
Update the document introduction to note that the Arduino Due is also
now supported.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-28 12:12:44 -04:00
Kevin O'Connor
654546e338 stepper: Support stepper phase adjustments when homing
Add support for enhancing the precision of endstop switches by also
inspecting the phase of the stepper motor when the endstop triggers.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-28 11:22:28 -04:00
Kevin O'Connor
170389ef14 extruder: Add some additional comments
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-26 11:17:26 -04:00
Kevin O'Connor
a17229a4c1 docs: ARM updates for Code_Overview.md
Some details on the code flow and organization have changed since
support for ARM processors was added.  Update Code_Overview.md
accordingly.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-26 10:58:33 -04:00
Kevin O'Connor
92f81d51f4 homing: Move low-level coordinate manipulation to kinematic class
Rework the code so that the kinematic class (currently just
cartesian.py) has more control over the homing process.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-25 23:47:30 -04:00
Kevin O'Connor
e9c03f2e4a gcode: Error on G20 (set units to inches) command
Respond with an error to a G20 command (instead of effectively
ignoring the command).

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-25 22:46:11 -04:00
Kevin O'Connor
dc37a07a8e extruder: Add support for "pressure advance" on extrusion
Add a config option to define an amount of additional filament to feed
into the extruder during acceleration and deceleration of the
extruder.  This can help ensure plastic is deposited in the correct
places during a print.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-25 21:57:23 -04:00
Kevin O'Connor
c847606311 toolhead: Limit lookahead optimization to moves with similar extrude ratios
Only skip acceleration between moves if both moves perform a similar
amount of extrusion.  This ensures the extruder has sufficient time to
accelerate to and from each extrude move.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-22 15:42:19 -04:00
Kevin O'Connor
589017a3d6 stepper: Have caller calculate max jerk velocity
Allow the owner of the stepper object to cacluate the maximum step
jerk velocity.  This is used to ensure there is no communication error
between mcu and host.

Disable checking of jerk velocity for extruder stepper motors.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-22 15:42:18 -04:00
Kevin O'Connor
d3c27c514f toolhead: Add some comments to acceleration code
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-16 21:33:35 -04:00
Kevin O'Connor
777a0b817b serialhdl: Calculate baudadjust from MCU's baud instead of host baud
Store the baud rate the MCU is configured for in the "identify" data
and use that rate when calculating the baudadjust parameter.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-16 21:33:35 -04:00
Kevin O'Connor
4988ba9a71 stepcompress: Fix error causing queue to not be expanded in expand_queue()
The test to check if the queue only needed to be moved was not correct
and it could lead to a segfault if clean_queue() was called instead of
actually increasing the queue size.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-16 21:33:35 -04:00
Kevin O'Connor
3fa7da804d stepcompress: Check for invalid count in step_factor and step_sqrt
Check for an invalid count and report an error if found.  This
prevents some segfaults when count goes negative.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-16 21:33:15 -04:00
Kevin O'Connor
af99ab1645 extruder: Create a new class and python file to track the printer extruder
Create a new python file (extruder.py) to control the extruder heater
and stepper motors.  This separates the extruder control logic from
the cartesian robot code - making it easier to customize both the
kinematic control of the robot as well as the extruder.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-10 22:49:02 -04:00
Kevin O'Connor
4a527a46ce stepper: Store max_velocity/max_accel instead of max_step_velocity/accel
All users of max_step_velocity and max_step_accel end up multiplying
by step_dist anyway, so it's easier to store max_velocity and
max_accel.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-10 22:49:02 -04:00
Kevin O'Connor
5829aa8bd7 toolhead: Avoid using a dummy_move for an empty move_queue
Explicitly check for when the move_queue is empty and only call
move.calc_junction() when there is a previous move.  This avoids the
need to create a dummy "sentinal" move object and it simplifies the
code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-10 22:49:01 -04:00
Kevin O'Connor
9bb1ae079f toolhead: Merge lookahead.py into toolhead.py
Remove the lookahead.py file and move its code directly into
toolhead.py.  The MoveQueue() class is small and tightly coupled to
the toolhead code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-10 22:49:01 -04:00
Kevin O'Connor
e0a9a1b800 toolhead: Split toolhead code from cartesian.py to new file toolhead.py
Separate out the toolhead logic to its own python file.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-10 22:48:59 -04:00
Kevin O'Connor
861f5a5387 cartesian: Separate out cartesian robot handling from ToolHead class
Separate out the low-level stepper motor kinematics handling from the
ToolHead class into its own class.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-10 22:47:54 -04:00
Kevin O'Connor
20ae4e5d98 cartesian: Rename CartKinematics class to ToolHead
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-10 22:47:13 -04:00
Kevin O'Connor
b3e8b430e5 cartesian: Do acceleration and lookahead on requested coordinates
Perform all acceleration calculations and lookahead checks in
millimeters using the cartesian coordinate system of the request.  The
conversion to step coordinates is now done at the time of the step
timing creation.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-10 22:47:08 -04:00
Kevin O'Connor
ae8d57e650 stepcompress: Fix compress_bisect_add() infinite loop
At high step speeds, it is possible to exit the inner scan due to
integer truncation.  Always update minadd or maxadd so that the outer
loop always terminates.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-10 21:46:57 -04:00
Kevin O'Connor
b0b2e9c4aa build: Avoid objcopy --dump-section flag
Commit da305e6b changed the objcopy command to use the --dump-section
flag.  However, the 2.24 version of avr-objcopy (which is common on
raspbian installs) does not support this flag.  Avoid using
--dump-section and continue to use the -j option instead.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-07-10 21:46:57 -04:00
Kevin O'Connor
409904c61c pins: Add Arduino Due pin name aliases
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-14 15:41:18 -04:00
Kevin O'Connor
afb1839b6b docs: Update documentation with Arduino Due installation info
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-14 15:17:03 -04:00
Kevin O'Connor
cc62a3dbf3 sam3x8e: Add initial support for Arduino Due boards
This adds basic support for running on the Atmel SAM3x8e
micro-controllers that are found in the Arudino Due boards.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-14 14:27:30 -04:00
Kevin O'Connor
31c04261c1 lib: Add Atmel SAM3x8e ARM CMSIS files
Add the ARM CMSIS definitions (obtained from an Arduino copy of
libsam) in preparation for Arduino Due support.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-14 14:25:42 -04:00
Kevin O'Connor
6220cdda92 stepper: Support rescheduling of step events on faster MCUs
On faster MCUs the step and unstep events may be too close for the
stepper motor driver.  Add a CONFIG_NO_UNSTEP_DELAY build option and
support the case where it is not set.  This allows faster MCUs to
schedule two events for each step (one for the step and one for the
unstep).

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-14 14:24:14 -04:00
Kevin O'Connor
da305e6b61 build: Update declfuncs.lds.S to only use progmem sections on AVR
On non-avr platforms the declfunc stuff still needs to be in the
binary in a rodata section.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-14 14:00:57 -04:00
Kevin O'Connor
343de9c454 serialhdl: Avoid using 1200 baud during serial reset
The Arduino Due uses a 1200 baud connection to signal an erase
sequence, so avoid it during normal serial resets.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-14 14:00:57 -04:00
Kevin O'Connor
e59951c8ae avr/serial: Separate out low-level hardware manipulation to its own function
Introduce enable_tx_irq() for manipulating the AVR hardware.  This
keeps the low-level hardware code together.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-14 14:00:57 -04:00
Kevin O'Connor
ea5f825a91 build: Default to O2 optimization
Default to O2 and set Os in the AVR makefile.  Platforms besides AVR
are likely to produce better code with O2 so make that the default.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-14 14:00:57 -04:00
Kevin O'Connor
b3e4ff7ef0 sched: Use 'unsigned int' instead of 'uint16_t' for shutdown reason
Use 'unsigned int' instead of 'uint16_t' as is faster on some
platforms.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-14 14:00:57 -04:00
Kevin O'Connor
b0524947e5 sched: Use uint_fast8_t for return type of timers
Some architectures are faster passing regular integers than 8bit
integers.  Use uint_fast8_t so that the architecture chooses the
appropriate type.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-14 14:00:53 -04:00
Kevin O'Connor
fa85094cbb irq: Allow boards to define the return type of irq_save()
The AVR wants a uint8_t return type for irq_save(), but other
architectures will generally prefer int.  Allow the board to configure
the size of the flag by introducing an irqstatus_t typedef.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-13 23:18:59 -04:00
Kevin O'Connor
9dd101c26f irq: Prefer irq_disable/enable instead of irq_save/restore in cmds/tasks
Task and command handlers always run with irqs enabled, so it is not
necessary to save/restore the irq state when disabling irqs in these
handlers.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-13 23:18:59 -04:00
Kevin O'Connor
4fcf5a31f5 pwmcmds: Add Kconfig option to allow boards to disable hardware PWM commands
Some boards may not support hardware based PWM.  Update the build so
that those commands do not need to be compiled if they are not
available.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-13 23:18:59 -04:00
Kevin O'Connor
c20f993747 spicmds: Add Kconfig option to allow boards to disable SPI commands
Some boards may not support SPI transfers.  Update the build so that
those commands do not need to be compiled if they are not available.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-13 23:18:59 -04:00
Kevin O'Connor
71947d6bea gpiocmds: Add Kconfig option to allow boards to disable ADC commands
Some boards may not support the ADC hardware.  Update the build so
that those commands do not need to be compiled if they are not
available.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-13 23:18:59 -04:00
Kevin O'Connor
220a1e4197 compiler.h: Check if __aligned and __section macros are already defined
Don't define these macros if they are already - doing so causes
compiler warnings.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-13 23:18:59 -04:00
Kevin O'Connor
4dd3478fc1 Makefile: Move listing of directories to create to board makefiles
Rename DIRS to dirs-y and populate it in the per-board Makefile rules.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-13 23:18:59 -04:00
Kevin O'Connor
8e1c0941b0 generic: Add new file generic/io.h and move read/writeb() to it
Move the definitions of the readb() style functions to a new header
generic/io.h.  This eliminates the dependency of stdint.h on
compiler.h.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-13 23:18:59 -04:00
Kevin O'Connor
62f96f0911 generic: Move simulator/gpio.h to generic/gpio.h
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-13 23:18:59 -04:00
Kevin O'Connor
73f3b0636a generic: Move simulator/irq.h to new file generic/irq.h
Move the generic irq definitions into generic/irq.h and move the
simulator irq code into main.c.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-13 23:18:58 -04:00
Kevin O'Connor
9f8817a47e generic: Move board timer.h files into generic/misc.h
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-13 23:18:58 -04:00
Kevin O'Connor
9971f999b3 generic: Create generic board infrastructure and move misc.h to it
Instead of creating a misc.h file in each board directory, create a
generic board directory and declare misc.h there.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-13 23:18:58 -04:00
Kevin O'Connor
ff789058df console: Update the debugging console to support setting local varables
Add a "SET varname value" local command to the console.py script.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-13 23:18:58 -04:00
Kevin O'Connor
bd07cd1193 sched: Optimize timer list handling
Rework the timer list rescheduling to be more optimized.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-13 15:34:56 -04:00
Kevin O'Connor
a6de2184ba stepper: Optimize for case where add is zero
At high rates, the "add" field is frequently zero.  It's possible to
optimize for that case.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-13 15:34:56 -04:00
Kevin O'Connor
bb3b881e21 docs: Change the debugging docs to recommend a serial baud rate of 250000
A baud of 250000 is a better choice for production use.  It's better
to test with that rate also.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-13 15:34:23 -04:00
Kevin O'Connor
e4859d2e9a gpio: Fix off-by-one bug in check for the maximum gpio port
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-13 15:34:23 -04:00
Kevin O'Connor
91e7807af6 avr: Add config option to clear the CPU prescaler
Some AVR chips ship with a 1/8th clock divisor set.  Add a compile
time option to manually clear this field at startup.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-05 10:52:46 -04:00
Kevin O'Connor
38f1d78e1b serialqueue: Add debugging helper functions for dumping a binary buffer
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-05 10:52:46 -04:00
Kevin O'Connor
b52b65624b avr: Separate out gpio pwm pin definitions from pwm register definitions
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-05 10:52:46 -04:00
Kevin O'Connor
2a17d9457a avr: Eliminate gpio_adc_info struct in gpio adc pin definitions
The gpio_adc_info only contains a single uint8_t field - it's simpler
to use an array of uint8_t instead.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-05 10:52:46 -04:00
Kevin O'Connor
7531d0c678 avr: Define timer1 timers and prevent their use as PWM at runtime
Instead of commenting out the timer1 pwm definitions, detect them at
runtime.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-05 10:52:45 -04:00
Kevin O'Connor
3eafc83458 avr: Initial support for Atmel AT90USB1286 mcu
Add GPIO definitions for the AT90USB1286.  Add code for communicating
over USB port on AT90USB1286.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-05 10:52:45 -04:00
Kevin O'Connor
4326a3adce buildcommands: Fix max_size calculation
The maximum max_size value should not include MESSAGE_MIN - that is
already added by the runtime code.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-05 10:52:45 -04:00
Kevin O'Connor
ed103822f5 sched: Change sched_from_ms() to sched_from_us()
Some code may require micro-second precision so update sched_from_ms()
to use micro-seconds.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-02 17:52:11 -04:00
Kevin O'Connor
d68cb264c4 stepper: Use stepper_stop() instead of stepper_reset() in stepper_shutdown()
The stepper_stop() function is equivalent to stepper_reset() during a
shutdown event.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-02 17:52:05 -04:00
Kevin O'Connor
45ba03efa3 timer: Move union u32_u16_u from compiler.h to avr/timer.c
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-06-01 09:54:13 -04:00
Kevin O'Connor
f582a36e4d Initial commit of source code.
Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
2016-05-25 11:37:40 -04:00
262 changed files with 44543 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@@ -0,0 +1,5 @@
out
*.so
*.pyc
.config
.config.old

674
COPYING Normal file
View File

@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.

126
Makefile Normal file
View File

@@ -0,0 +1,126 @@
# Klipper build system
#
# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
# Output directory
OUT=out/
# Kconfig includes
export HOSTCC := $(CC)
export CONFIG_SHELL := sh
export KCONFIG_AUTOHEADER := autoconf.h
export KCONFIG_CONFIG := $(CURDIR)/.config
-include $(KCONFIG_CONFIG)
# Common command definitions
CC=$(CROSS_PREFIX)gcc
AS=$(CROSS_PREFIX)as
LD=$(CROSS_PREFIX)ld
OBJCOPY=$(CROSS_PREFIX)objcopy
OBJDUMP=$(CROSS_PREFIX)objdump
STRIP=$(CROSS_PREFIX)strip
CPP=cpp
PYTHON=python
# Source files
src-y =
dirs-y = src
# Default compiler flags
cc-option=$(shell if test -z "`$(1) $(2) -S -o /dev/null -xc /dev/null 2>&1`" \
; then echo "$(2)"; else echo "$(3)"; fi ;)
CFLAGS-y := -I$(OUT) -Isrc -I$(OUT)board-generic/ -O2 -MD -g \
-Wall -Wold-style-definition $(call cc-option,$(CC),-Wtype-limits,) \
-ffunction-sections -fdata-sections
CFLAGS-y += -flto -fwhole-program -fno-use-linker-plugin
LDFLAGS-y := -Wl,--gc-sections -fno-whole-program
CPPFLAGS = -I$(OUT) -P -MD -MT $@
CFLAGS = $(CFLAGS-y)
LDFLAGS = $(LDFLAGS-y)
# Default targets
target-y := $(OUT)klipper.elf
all:
# Run with "make V=1" to see the actual compile commands
ifdef V
Q=
else
Q=@
MAKEFLAGS += --no-print-directory
endif
# Include board specific makefile
include src/Makefile
-include src/$(patsubst "%",%,$(CONFIG_BOARD_DIRECTORY))/Makefile
################ Common build rules
$(OUT)%.o: %.c $(OUT)autoconf.h $(OUT)board-link
@echo " Compiling $@"
$(Q)$(CC) $(CFLAGS) -c $< -o $@
################ Main build rules
$(OUT)board-link: $(KCONFIG_CONFIG)
@echo " Creating symbolic link $(OUT)board"
$(Q)mkdir -p $(addprefix $(OUT), $(dirs-y))
$(Q)touch $@
$(Q)ln -Tsf $(PWD)/src/$(CONFIG_BOARD_DIRECTORY) $(OUT)board
$(Q)mkdir -p $(OUT)board-generic
$(Q)ln -Tsf $(PWD)/src/generic $(OUT)board-generic/board
$(OUT)declfunc.lds: src/declfunc.lds.S
@echo " Precompiling $@"
$(Q)$(CPP) $(CPPFLAGS) -D__ASSEMBLY__ $< -o $@
$(OUT)klipper.o: $(patsubst %.c, $(OUT)src/%.o,$(src-y)) $(OUT)declfunc.lds
@echo " Linking $@"
$(Q)$(CC) $(CFLAGS) $(CFLAGS_klipper.o) -Wl,-r -Wl,-T,$(OUT)declfunc.lds -nostdlib $(patsubst %.c, $(OUT)src/%.o,$(src-y)) -o $@
$(OUT)compile_time_request.o: $(OUT)klipper.o ./scripts/buildcommands.py
@echo " Building $@"
$(Q)$(OBJCOPY) -j '.compile_time_request' -O binary $< $(OUT)klipper.o.compile_time_request
$(Q)$(PYTHON) ./scripts/buildcommands.py -d $(OUT)klipper.dict $(OUT)klipper.o.compile_time_request $(OUT)compile_time_request.c
$(Q)$(CC) $(CFLAGS) -c $(OUT)compile_time_request.c -o $@
$(OUT)klipper.elf: $(OUT)klipper.o $(OUT)compile_time_request.o
@echo " Linking $@"
$(Q)$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@
################ Kconfig rules
define do-kconfig
$(Q)mkdir -p $(OUT)/scripts/kconfig/lxdialog
$(Q)mkdir -p $(OUT)/include/config
$(Q)$(MAKE) -C $(OUT) -f $(CURDIR)/scripts/kconfig/Makefile srctree=$(CURDIR) src=scripts/kconfig obj=scripts/kconfig Q=$(Q) Kconfig=$(CURDIR)/src/Kconfig $1
endef
$(OUT)autoconf.h : $(KCONFIG_CONFIG) ; $(call do-kconfig, silentoldconfig)
$(KCONFIG_CONFIG): src/Kconfig ; $(call do-kconfig, olddefconfig)
%onfig: ; $(call do-kconfig, $@)
help: ; $(call do-kconfig, $@)
################ Generic rules
# Make definitions
.PHONY : all clean distclean FORCE
.DELETE_ON_ERROR:
all: $(target-y)
clean:
$(Q)rm -rf $(OUT)
distclean: clean
$(Q)rm -f .config .config.old
-include $(OUT)*.d $(patsubst %,$(OUT)%/*.d,$(dirs-y))

29
README.md Normal file
View File

@@ -0,0 +1,29 @@
Welcome to the Klipper project!
This project implements a 3d-printer firmware. There are two parts to
this firmware - code that runs on a micro-controller and code that
runs on a host machine. The host software does the work to build a
schedule of events, while the micro-controller software does the work
to execute the provided schedule at the specified times.
See the [features](docs/Features.md) document to find out why you
should use Klipper. To begin using Klipper start by
[installing](docs/Installation.md) it.
There is also [developer documentation](docs/Overview.md) available.
License
=======
Klipper is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Klipper is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Klipper. If not, see <http://www.gnu.org/licenses/>.

78
config/avrsim.cfg Normal file
View File

@@ -0,0 +1,78 @@
# Support for internal testing with the "simulavr" program. To use
# this config, compile the firmware for an AVR atmega644p, disable the
# AVR watchdog timer, set the MCU frequency to 20000000, and set the
# serial baud rate to 250000.
[stepper_x]
# Pins: PA5, PA4, PA1
step_pin: ar29
dir_pin: ar28
enable_pin: ar25
step_distance: .0225
endstop_pin: ^ar0
position_min: -0.25
position_endstop: 0
position_max: 200
[stepper_y]
# Pins: PA3, PA2
step_pin: ar27
dir_pin: ar26
enable_pin: ar25
step_distance: .0225
endstop_pin: ^ar1
position_min: -0.25
position_endstop: 0
position_max: 200
[stepper_z]
# Pins: PC7, PC6
step_pin: ar23
dir_pin: ar22
enable_pin: ar25
step_distance: .005
endstop_pin: ^ar2
position_min: 0.1
position_endstop: 0.5
position_max: 200
[extruder]
# Pins: PC3, PC2
step_pin: ar19
dir_pin: ar18
enable_pin: ar25
step_distance: .004242
nozzle_diameter: 0.500
filament_diameter: 3.500
heater_pin: ar4
sensor_type: EPCOS 100K B57560G104F
sensor_pin: analog1
control: pid
pid_Kp: 22.2
pid_Ki: 1.08
pid_Kd: 114
min_temp: 0
min_extrude_temp: 0
max_temp: 210
[heater_bed]
heater_pin: ar3
sensor_type: EPCOS 100K B57560G104F
sensor_pin: analog0
control: watermark
min_temp: 0
max_temp: 110
[fan]
pin: ar14
[mcu]
serial: /tmp/pseudoserial
pin_map: arduino
[printer]
kinematics: cartesian
max_velocity: 500
max_accel: 3000
max_z_velocity: 250
max_z_accel: 30

84
config/example-corexy.cfg Normal file
View File

@@ -0,0 +1,84 @@
# This file serves as documentation for config parameters of corexy
# style printers. One may copy and edit this file to configure a new
# corexy printer. Only parameters unique to corexy printers are
# described here - see the "example.cfg" file for description of
# common config parameters.
# DO NOT COPY THIS FILE WITHOUT CAREFULLY READING AND UPDATING IT
# FIRST. Incorrectly configured parameters may cause damage.
# The stepper_x section is used to describe the X axis as well as the
# stepper controlling the X+Y movement
[stepper_x]
step_pin: ar54
dir_pin: ar55
enable_pin: !ar38
step_distance: .01
endstop_pin: ^ar2
homing_speed: 50.0
position_min: 0
position_endstop: 0
position_max: 200
# The stepper_y section is used to describe the Y axis as well as the
# stepper controlling the X-Y movement
[stepper_y]
step_pin: ar60
dir_pin: ar61
enable_pin: !ar56
step_distance: .01
endstop_pin: ^ar15
homing_speed: 50.0
position_min: 0
position_endstop: 0
position_max: 200
[stepper_z]
step_pin: ar46
dir_pin: ar48
enable_pin: !ar62
step_distance: .01
endstop_pin: ^ar19
position_min: 0.1
position_endstop: 0.5
position_max: 200
[extruder]
step_pin: ar26
dir_pin: ar28
enable_pin: !ar24
step_distance: .0022
nozzle_diameter: 0.400
filament_diameter: 1.750
heater_pin: ar10
sensor_type: ATC Semitec 104GT-2
sensor_pin: analog13
control: pid
pid_Kp: 22.2
pid_Ki: 1.08
pid_Kd: 114
min_temp: 0
max_temp: 250
[heater_bed]
heater_pin: ar8
sensor_type: EPCOS 100K B57560G104F
sensor_pin: analog14
control: watermark
min_temp: 0
max_temp: 130
[fan]
pin: ar9
[mcu]
serial: /dev/ttyACM0
pin_map: arduino
[printer]
kinematics: corexy
# This option must be "corexy" for corexy printers.
max_velocity: 300
max_accel: 3000
max_z_velocity: 25
max_z_accel: 30

103
config/example-delta.cfg Normal file
View File

@@ -0,0 +1,103 @@
# This file serves as documentation for config parameters of delta
# style printers. One may copy and edit this file to configure a new
# delta printer. Only parameters unique to delta printers are
# described here - see the "example.cfg" file for description of
# common config parameters.
# DO NOT COPY THIS FILE WITHOUT CAREFULLY READING AND UPDATING IT
# FIRST. Incorrectly configured parameters may cause damage.
# The stepper_a section describes the stepper controlling the front
# left tower (at 210 degrees). This section also controls the homing
# parameters (homing_speed, homing_retract_dist) for all towers.
[stepper_a]
step_pin: ar54
dir_pin: ar55
enable_pin: !ar38
step_distance: .01
endstop_pin: ^ar2
homing_speed: 50.0
position_endstop: 297.05
# The stepper_b section describes the stepper controlling the front
# right tower (at 330 degrees)
[stepper_b]
step_pin: ar60
dir_pin: ar61
enable_pin: !ar56
step_distance: .01
endstop_pin: ^ar15
position_endstop: 297.05
# The stepper_c section describes the stepper controlling the rear
# tower (at 90 degrees)
[stepper_c]
step_pin: ar46
dir_pin: ar48
enable_pin: !ar62
step_distance: .01
endstop_pin: ^ar19
position_endstop: 297.05
[extruder]
step_pin: ar26
dir_pin: ar28
enable_pin: !ar24
step_distance: .0022
nozzle_diameter: 0.400
filament_diameter: 1.750
heater_pin: ar10
sensor_type: ATC Semitec 104GT-2
sensor_pin: analog13
control: pid
pid_Kp: 22.2
pid_Ki: 1.08
pid_Kd: 114
min_temp: 0
max_temp: 250
[heater_bed]
heater_pin: ar8
sensor_type: EPCOS 100K B57560G104F
sensor_pin: analog14
control: watermark
min_temp: 0
max_temp: 130
# Extruder print fan (omit section if fan not present)
#[fan]
#pin: ar9
[mcu]
serial: /dev/ttyACM0
pin_map: arduino
[printer]
kinematics: delta
# This option must be "delta" for linear delta printers.
max_velocity: 300
# Maximum velocity (in mm/s) of the toolhead relative to the
# print. This limits the velocity of the toolhead relative to the
# print - at the extreme end of the print envelope the delta axis
# steppers themselves may briefly exceed this speed by up to 3
# times. This parameter must be specified.
max_accel: 3000
# Maximum acceleration (in mm/s^2) of the toolhead relative to the
# print. This limits the acceleration of the toolhead relative to
# the print - at the extreme end of the print envelope the delta
# axis steppers may briefly exceed this acceleration by up to 3
# times. This parameter must be specified.
max_z_velocity: 200
# For delta printers this limits the maximum velocity (in mm/s) of
# moves with z axis movement. This setting can be used to reduce the
# maximum speed of up/down moves (which require a higher step rate
# than other moves on a delta printer). The default is to use
# max_velocity for max_z_velocity.
delta_arm_length: 333.0
# Length (in mm) of the diagonal rods that connect the linear axes
# to the print head. This parameter must be provided.
delta_radius: 174.75
# Radius (in mm) of the horizontal circle formed by the three linear
# axis towers. This parameter may also be calculated as:
# delta_radius = smooth_rod_offset - effector_offset - carriage_offset
# This parameter must be provided.

296
config/example.cfg Normal file
View File

@@ -0,0 +1,296 @@
# This file serves as documentation for config parameters. One may
# copy and edit this file to configure a new cartesian style
# printer. For delta style printers, see the "example-delta.cfg"
# file. For corexy/h-bot style printers, see the "example-corexy.cfg"
# file.
# DO NOT COPY THIS FILE WITHOUT CAREFULLY READING AND UPDATING IT
# FIRST. Incorrectly configured parameters may cause damage.
# A note on pin names: pins may be configured with a hardware name
# (such as "PA4") or with an Arduino alias name (such as "ar29" or
# "analog3"). In order to use Arduino names, the pin_map variable in
# the mcu section must be present and have a value of "arduino".
# Pin names may be preceded by an '!' to indicate that a reverse
# polarity should be used (eg, trigger on low instead of high). Input
# pins may be preceded by a '^' to indicate that a hardware pull-up
# resistor should be enabled for the pin.
# The stepper_x section is used to describe the stepper controlling
# the X axis in a cartesian robot
[stepper_x]
step_pin: ar29
# Step GPIO pin (triggered high). This parameter must be provided.
dir_pin: !ar28
# Direction GPIO pin (high indicates positive direction). This
# parameter must be provided.
enable_pin: !ar25
# Enable pin (default is enable high; use ! to indicate enable
# low). If this parameter is not provided then the stepper motor
# driver must always be enabled.
step_distance: .0225
# Distance in mm that each step causes the axis to travel. This
# parameter must be provided.
endstop_pin: ^ar0
# Endstop switch detection pin. This parameter must be provided for
# the X, Y, and Z steppers on cartesian style printers.
#homing_speed: 5.0
# Maximum velocity (in mm/s) of the stepper when homing. The default
# is 5mm/s.
#homing_retract_dist: 5.0
# Distance to backoff (in mm) before homing a second time during
# homing. The default is 5mm.
#homing_positive_dir: False
# If true, homes in a positive direction (away from zero). The
# default is False.
#homing_stepper_phases: 0
# One may optionally set this to the number of phases of the stepper
# motor driver (which is the number of micro-steps multiplied by
# four). When set, the phase of the stepper driver will be used
# during homing to improve the accuracy of the endstop switch.
#homing_endstop_accuracy: 0.200
# Sets the expected accuracy (in mm) of the endstop. This represents
# the maximum error distance the endstop may trigger (eg, if an
# endstop may occasionally trigger 100um early or up to 100um late
# then set this to 0.200 for 200um). This setting is used with
# homing_stepper_phases and is only useful if that parameter is also
# configured.
#homing_endstop_phase: 0
# This specifies the phase of the stepper motor driver to expect
# when hitting the endstop. This setting is only meaningful if
# homing_stepper_phases is also set. Only set this value if one is
# sure the stepper motor driver is reset every time the mcu is
# reset. If this is not set, but homing_stepper_phases is set, then
# the stepper phase will be detected on the first home and that
# phase will be used on all subsequent homes.
position_min: -0.25
# Minimum valid distance (in mm) the user may command the stepper to
# move to. The default is 0mm.
position_endstop: 0
# Location of the endstop (in mm). This parameter must be provided
# for the X, Y, and Z steppers on cartesian style printers.
position_max: 200
# Maximum valid distance (in mm) the user may command the stepper to
# move to. This parameter must be provided for the X, Y, and Z
# steppers on cartesian style printers.
# The stepper_y section is used to describe the stepper controlling
# the Y axis in a cartesian robot. It has the same settings as the
# stepper_x section
[stepper_y]
step_pin: ar27
dir_pin: ar26
enable_pin: !ar25
step_distance: .0225
endstop_pin: ^ar1
position_min: -0.25
position_endstop: 0
position_max: 200
# The stepper_z section is used to describe the stepper controlling
# the Z axis in a cartesian robot. It has the same settings as the
# stepper_x section
[stepper_z]
step_pin: ar23
dir_pin: !ar22
enable_pin: !ar25
step_distance: .005
endstop_pin: ^ar2
position_min: 0.1
position_endstop: 0.5
position_max: 200
# The extruder section is used to describe both the stepper
# controlling the printer extruder and the heater parameters for the
# nozzle. The stepper configuration has the same settings as the
# stepper_x section and the heater configuration has the same settings
# as the heater_bed section
[extruder]
step_pin: ar19
dir_pin: ar18
enable_pin: !ar25
step_distance: .004242
nozzle_diameter: 0.500
# Diameter of the nozzle orifice (in mm). This parameter must be
# provided.
filament_diameter: 3.500
# Diameter of the raw filament (in mm) as it enters the
# extruder. This parameter must be provided.
#max_extrude_cross_section:
# Maximum area of the cross section of an extrusion line (in
# mm^2). If a move requests an extrusion rate that would exceed this
# value it will cause an error to be returned. The default is: 4.0 *
# nozzle_diameter^2
#max_extrude_only_distance: 50.0
# Maximum length (in mm of raw filament) that an extrude only move
# may be. If an extrude only move requests a distance greater than
# this value it will cause an error to be returned. The default is
# 50mm.
#max_extrude_only_velocity:
# Maximum velocity (in mm/s) of the extruder motor for extrude only
# moves. If this is not specified then it is calculated to match the
# limit an XY printing move with a max_extrude_cross_section
# extrusion would have.
#max_extrude_only_accel:
# Maximum acceleration (in mm/s^2) of the extruder motor for extrude
# only moves. If this is not specified then it is calculated to
# match the limit an XY printing move with a
# max_extrude_cross_section extrusion would have.
#pressure_advance: 0.0
# The amount of raw filament to push into the extruder during
# extruder acceleration. An equal amount of filament is retracted
# during deceleration. It is measured in millimeters per
# millimeter/second. The default is 0, which disables pressure
# advance.
#pressure_advance_lookahead_time: 0.010
# A time (in seconds) to "look ahead" at future extrusion moves when
# calculating pressure advance. This is used to reduce the
# application of pressure advance during cornering moves that would
# otherwise cause retraction followed immediately by pressure
# buildup. This setting only applies if pressure_advance is
# non-zero. The default is 0.010 (10 milliseconds).
#
# The remaining variables describe the extruder heater
heater_pin: ar4
# PWM output pin controlling the heater. This parameter must be
# provided.
#max_power: 1.0
# The maximum power (expressed as a value from 0.0 to 1.0) that the
# heater_pin may be set to. The value 1.0 allows the pin to be set
# fully enabled for extended periods, while a value of 0.5 would
# allow the pin to be enabled for no more than half the time. This
# setting may be used to limit the total power output (over extended
# periods) to the heater. The default is 1.0.
sensor_type: EPCOS 100K B57560G104F
# Type of sensor - this may be "EPCOS 100K B57560G104F", "ATC
# Semitec 104GT-2", or "AD595". This parameter must be provided.
sensor_pin: analog1
# Analog input pin connected to the sensor. This parameter must be
# provided.
#pullup_resistor: 4700
# The resistance (in ohms) of the pullup attached to the
# thermistor. This parameter is only valid when the sensor is a
# thermistor. The default is 4700 ohms.
#adc_voltage: 5.0
# The ADC comparison voltage. This parameter is only valid when the
# sensor is an AD595. The default is 5 volts.
control: pid
# Control algorithm (either pid or watermark). This parameter must
# be provided.
pid_Kp: 22.2
# Kp is the "proportional" constant for the pid. This parameter must
# be provided for PID heaters.
pid_Ki: 1.08
# Ki is the "integral" constant for the pid. This parameter must be
# provided for PID heaters.
pid_Kd: 114
# Kd is the "derivative" constant for the pid. This parameter must
# be provided for PID heaters.
#pid_deriv_time: 2.0
# A time value (in seconds) over which the derivative in the pid
# will be smoothed to reduce the impact of measurement noise. The
# default is 2 seconds.
#pid_integral_max:
# The maximum "windup" the integral term may accumulate. The default
# is to use the same value as max_power.
#min_extrude_temp: 170
# The minimum temperature (in Celsius) at which extruder move
# commands may be issued. The default is 170 Celsius.
min_temp: 0
# Minimum temperature in Celsius (mcu will shutdown if not
# met). This parameter must be provided.
max_temp: 210
# Maximum temperature (mcu will shutdown if temperature is above
# this value). This parameter must be provided.
# The heater_bed section describes a heated bed (if present - omit
# section if not present).
[heater_bed]
heater_pin: ar3
sensor_type: EPCOS 100K B57560G104F
sensor_pin: analog0
control: watermark
#max_delta: 2.0
# On 'watermark' controlled heaters this is the number of degrees in
# Celsius above the target temperature before disabling the heater
# as well as the number of degrees below the target before
# re-enabling the heater. The default is 2 degrees Celsius.
min_temp: 0
max_temp: 110
# Extruder print fan (omit section if fan not present)
[fan]
pin: ar14
# PWM output pin controlling the fan. This parameter must be
# provided.
#hard_pwm: 0
# Set this value to force hardware PWM instead of software PWM. Set
# to 1 to force a hardware PWM at the fastest rate; set to a higher
# number to force hardware PWM with the given cycle time in clock
# ticks. The default is 0 which enables software PWM with a cycle
# time of 10ms.
#kick_start_time: 0.100
# Time (in seconds) to run the fan at full speed when first enabling
# it (helps get the fan spinning). The default is 0.100 seconds.
# Micro-controller information
[mcu]
serial: /dev/ttyACM0
# The serial port to connect to the MCU. The default is /dev/ttyS0
#baud: 250000
# The baud rate to use. The default is 250000.
pin_map: arduino
# This option may be used to enable Arduino pin name aliases. The
# default is to not enable the aliases.
#restart_method: arduino
# This controls the mechanism the host will use to reset the
# micro-controller. The choices are 'arduino', 'rpi_usb', and
# 'command'. The 'arduino' method (toggle DTR; set baud to 1200) is
# common on Arduino boards and clones. The 'rpi_usb' method is
# useful on Raspberry Pi boards with micro-controllers powered over
# USB - it briefly disables power to all USB ports to accomplish a
# micro-controller reset. The 'command' method involves sending a
# Klipper command to the micro-controller so that it can reset
# itself. The default is 'arduino'.
custom:
# This option may be used to specify a set of custom
# micro-controller commands to be sent at the start of the
# connection. It may be used to configure the initial settings of
# LEDs, to configure micro-stepping pins, to configure a digipot,
# etc.
# The printer section controls high level printer settings
[printer]
kinematics: cartesian
# This option must be "cartesian" for cartesian printers.
max_velocity: 500
# Maximum velocity (in mm/s) of the toolhead (relative to the
# print). This parameter must be specified.
max_accel: 3000
# Maximum acceleration (in mm/s^2) of the toolhead (relative to the
# print). This parameter must be specified.
#max_accel_to_decel:
# A pseudo acceleration (in mm/s^2) controlling how fast the
# toolhead may go from acceleration to deceleration. It is used to
# reduce the top speed of short zig-zag moves (and thus reduce
# printer vibration from these moves). The default is half of
# max_accel.
max_z_velocity: 25
# For cartesian printers this sets the maximum velocity (in mm/s) of
# movement along the z axis. This setting can be used to restrict
# the maximum speed of the z stepper motor on cartesian
# printers. The default is to use max_velocity for max_z_velocity.
max_z_accel: 30
# For cartesian printers this sets the maximum acceleration (in
# mm/s^2) of movement along the z axis. It limits the acceleration
# of the z stepper motor on cartesian printers. The default is to
# use max_accel for max_z_accel.
#motor_off_time: 600
# Time (in seconds) of idle time before the printer will try to
# disable active motors. The default is 600 seconds.
#junction_deviation: 0.02
# Distance (in mm) used to control the internal approximated
# centripetal velocity cornering algorithm. A larger number will
# permit higher "cornering speeds" at the junction of two moves. The
# default is 0.02mm.

90
config/generic-rambo.cfg Normal file
View File

@@ -0,0 +1,90 @@
# This file contains common pin mappings for RAMBo boards. To use this
# config, the firmware should be compiled for the AVR atmega2560.
# See the example.cfg file for a description of available parameters.
[stepper_x]
step_pin: PC0
dir_pin: PL1
enable_pin: !PA7
step_distance: .0125
endstop_pin: ^PB6
homing_speed: 50
position_endstop: 0
position_max: 200
[stepper_y]
step_pin: PC1
dir_pin: !PL0
enable_pin: !PA6
step_distance: .0125
endstop_pin: ^PB5
homing_speed: 50
position_endstop: 0
position_max: 200
[stepper_z]
step_pin: PC2
dir_pin: PL2
enable_pin: !PA5
step_distance: 0.00025
endstop_pin: ^PB4
homing_speed: 5
position_endstop: 0
position_max: 200
[extruder]
step_pin: PC3
dir_pin: PL6
enable_pin: !PA4
step_distance: .002
nozzle_diameter: 0.400
filament_diameter: 1.750
heater_pin: PH6
sensor_type: EPCOS 100K B57560G104F
sensor_pin: PF0
control: pid
pid_Kp: 22.2
pid_Ki: 1.08
pid_Kd: 114
min_temp: 0
max_temp: 250
[heater_bed]
heater_pin: PE5
sensor_type: EPCOS 100K B57560G104F
sensor_pin: PF2
control: watermark
min_temp: 0
max_temp: 130
[fan]
pin: PH5
[mcu]
serial: /dev/ttyACM0
custom:
# Turn off yellow led
set_digital_out pin=PB7 value=0
# Stepper micro-step pins
set_digital_out pin=PG1 value=1
set_digital_out pin=PG0 value=1
set_digital_out pin=PK7 value=1
set_digital_out pin=PG2 value=1
set_digital_out pin=PK6 value=1
set_digital_out pin=PK5 value=1
set_digital_out pin=PK3 value=1
set_digital_out pin=PK4 value=1
# Initialize digipot
send_spi_message pin=PD7 msg=0487 # X = ~0.75A
send_spi_message pin=PD7 msg=0587 # Y = ~0.75A
send_spi_message pin=PD7 msg=0387 # Z = ~0.75A
send_spi_message pin=PD7 msg=00A5 # E0
send_spi_message pin=PD7 msg=017D # E1
[printer]
kinematics: cartesian
max_velocity: 300
max_accel: 3000
max_z_velocity: 5
max_z_accel: 100

74
config/generic-ramps.cfg Normal file
View File

@@ -0,0 +1,74 @@
# This file contains common pin mappings for RAMPS (v1.3 and later)
# boards. RAMPS boards typically use a firmware compiled for the AVR
# atmega2560 (though other AVR chips are also possible).
# See the example.cfg file for a description of available parameters.
[stepper_x]
step_pin: ar54
dir_pin: ar55
enable_pin: !ar38
step_distance: .0125
endstop_pin: ^ar3
homing_speed: 50
position_endstop: 0
position_max: 200
[stepper_y]
step_pin: ar60
dir_pin: !ar61
enable_pin: !ar56
step_distance: .0125
endstop_pin: ^ar14
homing_speed: 50
position_endstop: 0
position_max: 200
[stepper_z]
step_pin: ar46
dir_pin: ar48
enable_pin: !ar62
step_distance: 0.00025
endstop_pin: ^ar18
homing_speed: 5
position_endstop: 0
position_max: 200
[extruder]
step_pin: ar26
dir_pin: ar28
enable_pin: !ar24
step_distance: .002
nozzle_diameter: 0.400
filament_diameter: 1.750
heater_pin: ar10
sensor_type: EPCOS 100K B57560G104F
sensor_pin: analog13
control: pid
pid_Kp: 22.2
pid_Ki: 1.08
pid_Kd: 114
min_temp: 0
max_temp: 250
[heater_bed]
heater_pin: ar8
sensor_type: EPCOS 100K B57560G104F
sensor_pin: analog14
control: watermark
min_temp: 0
max_temp: 130
[fan]
pin: ar9
[mcu]
serial: /dev/ttyACM0
pin_map: arduino
[printer]
kinematics: cartesian
max_velocity: 300
max_accel: 3000
max_z_velocity: 5
max_z_accel: 100

View File

@@ -0,0 +1,103 @@
# Support for Makergear M2 printers circa 2012 that have the RAMBo
# v1.0d electronics along with the V3A extruder. The electronics use
# Allegro A4984 stepper drivers with 1/8th micro-stepping. To use
# this config, the firmware should be compiled for the AVR atmega2560.
[stepper_x]
step_pin: PC0
dir_pin: !PL1
enable_pin: !PA7
step_distance: .0225
endstop_pin: ^!PB6
homing_speed: 50.0
homing_stepper_phases: 32
homing_endstop_accuracy: .200
position_min: -0.25
position_endstop: 0.0
position_max: 200
[stepper_y]
step_pin: PC1
dir_pin: PL0
enable_pin: !PA6
step_distance: .0225
endstop_pin: ^!PB5
homing_speed: 50.0
homing_stepper_phases: 32
homing_endstop_accuracy: .200
position_min: -0.25
position_endstop: 0.0
position_max: 250
[stepper_z]
step_pin: PC2
dir_pin: !PL2
enable_pin: !PA5
step_distance: .005
endstop_pin: ^!PB4
homing_speed: 4.0
homing_retract_dist: 2.0
homing_stepper_phases: 32
homing_endstop_accuracy: .050
position_min: 0.1
position_endstop: 0.7
position_max: 200
[extruder]
step_pin: PC3
dir_pin: PL6
enable_pin: !PA4
step_distance: .004242
nozzle_diameter: 0.350
filament_diameter: 1.750
pressure_advance: 0.07
heater_pin: PH6
sensor_type: EPCOS 100K B57560G104F
sensor_pin: PF0
control: pid
pid_Kp: 7.0
pid_Ki: 0.1
pid_Kd: 12
min_temp: 0
max_temp: 210
[heater_bed]
heater_pin: PE5
sensor_type: EPCOS 100K B57560G104F
sensor_pin: PF2
control: watermark
min_temp: 0
max_temp: 100
[fan]
pin: PH5
[mcu]
serial: /dev/ttyACM0
custom:
# Nozzle fan
set_pwm_out pin=PH3 cycle_ticks=1 value=155
# Turn off yellow led
set_digital_out pin=PB7 value=0
# Stepper micro-step pins
set_digital_out pin=PG1 value=1
set_digital_out pin=PG0 value=1
set_digital_out pin=PK7 value=1
set_digital_out pin=PG2 value=1
set_digital_out pin=PK6 value=1
set_digital_out pin=PK5 value=1
set_digital_out pin=PK3 value=1
set_digital_out pin=PK4 value=1
# Initialize digipot
send_spi_message pin=PD7 msg=0487 # X = ~0.75A
send_spi_message pin=PD7 msg=0587 # Y = ~0.75A
send_spi_message pin=PD7 msg=0387 # Z = ~0.75A
send_spi_message pin=PD7 msg=00A5 # E0
send_spi_message pin=PD7 msg=017D # E1
[printer]
kinematics: cartesian
max_velocity: 500
max_accel: 3000
max_z_velocity: 25
max_z_accel: 30

211
docs/Code_Overview.md Normal file
View File

@@ -0,0 +1,211 @@
This document describes the overall code layout and major code flow of
Klipper.
Directory Layout
================
The **src/** directory contains the C source for the micro-controller
code. The **src/avr/** directory contains specific code for Atmel
ATmega micro-controllers. The **src/sam3x8e/** directory contains code
specific to the Arduino Due style ARM micro-controllers. The
**src/simulator/** contains code stubs that allow the micro-controller
to be test compiled on other architectures. The **src/generic/**
directory contains helper code that may be useful across different
host architectures. The build arranges for includes of
"board/somefile.h" to first look in the current architecture directory
(eg, src/avr/somefile.h) and then in the generic directory (eg,
src/generic/somefile.h).
The **klippy/** directory contains the C and Python source for the
host part of the software.
The **lib/** directory contains external 3rd-party library code that
is necessary to build some targets.
The **config/** directory contains example printer configuration
files.
The **scripts/** directory contains build-time scripts useful for
compiling the micro-controller code.
During compilation, the build may create an **out/** directory. This
contains temporary build time objects. The final micro-controller
object that is built is **out/klipper.elf.hex** on AVR and
**out/klipper.bin** on ARM.
Micro-controller code flow
==========================
Execution of the micro-controller code starts in architecture specific
code (eg, **src/avr/main.c**) which ultimately calls sched_main()
located in **src/sched.c**. The sched_main() code starts by running
all functions that have been tagged with the DECL_INIT() macro. It
then goes on to repeatedly run all functions tagged with the
DECL_TASK() macro.
One of the main task functions is command_task() located in
**src/command.c**. This function processes incoming serial commands
and runs the associated command function for them. Command functions
are declared using the DECL_COMMAND() macro.
Task, init, and command functions always run with interrupts enabled
(however, they can temporarily disable interrupts if needed). These
functions should never pause, delay, or do any work that lasts more
than a few micro-seconds. These functions schedule work at specific
times by scheduling timers.
Timer functions are scheduled by calling sched_add_timer() (located in
**src/sched.c**). The scheduler code will arrange for the given
function to be called at the requested clock time. Timer interrupts
are initially handled in an architecture specific interrupt handler
(eg, **src/avr/timer.c**) which calls sched_timer_dispatch() located
in **src/sched.c**. The timer interrupt leads to execution of schedule
timer functions. Timer functions always run with interrupts
disabled. The timer functions should always complete within a few
micro-seconds. At completion of the timer event, the function may
choose to reschedule itself.
In the event an error is detected the code can invoke shutdown() (a
macro which calls sched_shutdown() located in **src/sched.c**).
Invoking shutdown() causes all functions tagged with the
DECL_SHUTDOWN() macro to be run. Shutdown functions always run with
interrupts disabled.
Much of the functionality of the micro-controller involves working
with General-Purpose Input/Output pins (GPIO). In order to abstract
the low-level architecture specific code from the high-level task
code, all GPIO events are implemented in architectures specific
wrappers (eg, **src/avr/gpio.c**). The code is compiled with gcc's
"-flto -fwhole-program" optimization which does an excellent job of
inlining functions across compilation units, so most of these tiny
gpio functions are inlined into their callers, and there is no
run-time cost to using them.
Klippy code overview
====================
The host code (Klippy) is intended to run on a low-cost computer (such
as a Raspberry Pi) paired with the micro-controller. The code is
primarily written in Python, however it does use CFFI to implement
some functionality in C code.
Initial execution starts in **klippy/klippy.py**. This reads the
command-line arguments, opens the printer config file, instantiates
the main printer objects, and starts the serial connection. The main
execution of G-code commands is in the process_commands() method in
**klippy/gcode.py**. This code translates the G-code commands into
printer object calls, which frequently translate the actions to
commands to be executed on the micro-controller (as declared via the
DECL_COMMAND macro in the micro-controller code).
There are four threads in the Klippy host code. The main thread
handles incoming gcode commands. A second thread (which resides
entirely in the **klippy/serialqueue.c** C code) handles low-level IO
with the serial port. The third thread is used to process response
messages from the micro-controller in the Python code (see
**klippy/serialhdl.py**). The fourth thread writes debug messages to
the log (see **klippy/queuelogger.py**) so that the other threads
never block on log writes.
Code flow of a move command
===========================
A typical printer movement starts when a "G1" command is sent to the
Klippy host and it completes when the corresponding step pulses are
produced on the micro-controller. This section outlines the code flow
of a typical move command. The [kinematics](Kinematics.md) document
provides further information on the mechanics of moves.
* Processing for a move command starts in gcode.py. The goal of
gcode.py is to translate G-code into internal calls. Changes in
origin (eg, G92), changes in relative vs absolute positions (eg,
G90), and unit changes (eg, F6000=100mm/s) are handled here. The
code path for a move is: `process_data() -> process_commands() ->
cmd_G1()`. Ultimately the ToolHead class is invoked to execute the
actual request: `cmd_G1() -> ToolHead.move()`
* The ToolHead class (in toolhead.py) handles "look-ahead" and tracks
the timing of printing actions. The codepath for a move is:
`ToolHead.move() -> MoveQueue.add_move() -> MoveQueue.flush() ->
Move.set_junction() -> Move.move()`.
* ToolHead.move() creates a Move() object with the parameters of the
move (in cartesian space and in units of seconds and millimeters).
* MoveQueue.add_move() places the move object on the "look-ahead"
queue.
* MoveQueue.flush() determines the start and end velocities of each
move.
* Move.set_junction() implements the "trapezoid generator" on a
move. The "trapezoid generator" breaks every move into three parts:
a constant acceleration phase, followed by a constant velocity
phase, followed by a constant deceleration phase. Every move
contains these three phases in this order, but some phases may be of
zero duration.
* When Move.move() is called, everything about the move is known -
its start location, its end location, its acceleration, its
start/crusing/end velocity, and distance traveled during
acceleration/cruising/deceleration. All the information is stored in
the Move() class and is in cartesian space in units of millimeters
and seconds. Times are stored relative to the start of the print.
The move is then handed off to the kinematics classes: `Move.move()
-> kin.move()`
* The goal of the kinematics classes is to translate the movement in
cartesian space to movement on each stepper. The kinematics classes
are in cartesian.py, corexy.py, delta.py, and extruder.py. The
kinematic class is given a chance to audit the move
(`ToolHead.move() -> kin.check_move()`) before it goes on the
look-ahead queue, but once the move arrives in *kin*.move() the
kinematic class is required to handle the move as specified. The
kinematic classes translate the three parts of each move
(acceleration, constant "cruising" velocity, and deceleration) to
the associated movement on each stepper. Note that the extruder is
handled in its own kinematic class. Since the Move() class specifies
the exact movement time and since step pulses are sent to the
micro-controller with specific timing, stepper movements produced by
the extruder class will be in sync with head movement even though
the code is kept separate.
* For efficiency reasons, the stepper pulse times are generated in C
code. The code flow is: `kin.move() -> MCU_Stepper.step_const() ->
stepcompress_push_const()`, or for delta kinematics:
`DeltaKinematics.move() -> MCU_Stepper.step_delta() ->
stepcompress_push_delta()`. The MCU_Stepper code just performs unit
and axis transformation (seconds to clock ticks and millimeters to
step distances), and calls the C code. The C code calculates the
stepper step times for each movement and fills an array (struct
stepcompress.queue) with the corresponding micro-controller clock
counter times (in 64bit integers) for every step. Here the
"micro-controller clock counter" value directly corresponds to the
micro-controller's hardware counter - it is relative to when the
micro-controller was last powered up.
* The next major step is to compress the steps: `stepcompress_flush()
-> compress_bisect_add()` (in stepcompress.c). This code generates
and encodes a series of micro-controller "queue_step" commands that
correspond to the list of stepper step times built in the previous
stage. These "queue_step" commands are then queued, prioritized, and
sent to the micro-controller (via stepcompress.c:steppersync and
serialqueue.c:serialqueue).
* Processing of the queue_step commands on the micro-controller starts
in command.c which parses the command and calls
`command_queue_step()`. The command_queue_step() code (in stepper.c)
just appends the parameters of each queue_step command to a per
stepper queue. Under normal operation the queue_step command is
parsed and queued at least 100ms before the time of its first
step. Finally, the generation of stepper events is done in
`stepper_event()`. It's called from the hardware timer interrupt at
the scheduled time of the first step. The stepper_event() code
generates a step pulse and then reschedules itself to run at the
time of the next step pulse for the given queue_step parameters. The
parameters for each queue_step command are "interval", "count", and
"add". At a high-level, stepper_event() runs the following, 'count'
times: `do_step(); next_wake_time = last_wake_time + interval;
interval += add;`
The above may seem like a lot of complexity to execute a
movement. However, the only really interesting parts are in the
ToolHead and kinematic classes. It's this part of the code which
specifies the movements and their timings. The remaining parts of the
processing is mostly just communication and plumbing.

150
docs/Debugging.md Normal file
View File

@@ -0,0 +1,150 @@
The Klippy host code has some tools to help in debugging.
Translating gcode files to micro-controller commands
====================================================
The Klippy host code can run in a batch mode to produce the low-level
micro-controller commands associated with a gcode file. Inspecting
these low-level commands is useful when trying to understand the
actions of the low-level hardware. It can also be useful to compare
the difference in micro-controller commands after a code change.
To run Klippy in this batch mode, there is a one time step necessary
to generate the micro-controller "data dictionary". This is done by
compiling the micro-controller code to obtain the **out/klipper.dict**
file:
```
make menuconfig
make
```
Once the above is done it is possible to run Klipper in batch mode
(see [installation](Installation.md) for the steps necessary to build
the python virtual environment and a printer.cfg file):
```
~/klippy-env/bin/python ./klippy/klippy.py ~/printer.cfg -i test.gcode -o test.serial -v -d out/klipper.dict
```
The above will produce a file **test.serial** with the binary serial
output. This output can be translated to readable text with:
```
~/klippy-env/bin/python ./klippy/parsedump.py out/klipper.dict test.serial > test.txt
```
The resulting file **test.txt** contains a human readable list of
micro-controller commands.
The batch mode disables certain response / request commands in order
to function. As a result, there will be some differences between
actual commands and the above output. The generated data is useful for
testing and inspection; it is not useful for sending to a real
micro-controller.
Testing with simulavr
=====================
The [simulavr](http://www.nongnu.org/simulavr/) tool enables one to
simulate an Atmel ATmega micro-controller. This section describes how
one can run test gcode files through simulavr. It is recommended to
run this on a desktop class machine (not a Raspberry Pi) as it does
require significant cpu to run efficiently.
To use simulavr, download the simulavr package and compile with python
support:
```
git clone git://git.savannah.nongnu.org/simulavr.git
cd simulavr
./bootstrap
./configure --enable-python
make
```
Note that the build system may need to have some packages (such as
swig) installed in order to build the python module. Make sure the
file **src/python/_pysimulavr.so** is present after the above
compilation.
To compile Klipper for use in simulavr, run:
```
cd /patch/to/klipper
make menuconfig
```
and compile the micro-controller software for an AVR atmega644p,
disable the AVR watchdog timer, and set the MCU frequency
to 20000000. Then one can compile Klipper (run `make`) and then start
the simulation with:
```
PYTHONPATH=/path/to/simulavr/src/python/ ./scripts/avrsim.py -m atmega644 -s 20000000 -b 250000 out/klipper.elf
```
Then, with simulavr running in another window, one can run the
following to read gcode from a file (eg, "test.gcode"), process it
with Klippy, and send it to Klipper running in simulavr (see
[installation](Installation.md) for the steps necessary to build the
python virtual environment):
```
~/klippy-env/bin/python ./klippy/klippy.py config/avrsim.cfg -i test.gcode -v
```
Using simulavr with gtkwave
---------------------------
One useful feature of simulavr is its ability to create signal wave
generation files with the exact timing of events. To do this, follow
the directions above, but run avrsim.py with a command-line like the
following:
```
PYTHONPATH=/path/to/simulavr/src/python/ ./scripts/avrsim.py -m atmega644 -s 20000000 -b 250000 out/klipper.elf -t PORTA.PORT,PORTC.PORT
```
The above would create a file **avrsim.vcd** with information on each
change to the GPIOs on PORTA and PORTB. This could then be viewed
using gtkwave with:
```
gtkwave avrsim.vcd
```
Manually sending commands to the micro-controller
-------------------------------------------------
Normally, Klippy would be used to translate gcode commands to Klipper
commands. However, it's also possible to manually send Klipper
commands (functions marked with the DECL_COMMAND() macro in the
Klipper source code). To do so, run:
```
~/klippy-env/bin/python ./klippy/console.py /tmp/pseudoserial 250000
```
Generating load graphs
======================
The Klippy log file (/tmp/klippy.log) stores statistics on bandwidth,
micro-controller load, and host buffer load. It can be useful to graph
these statistics after a print.
To generate a graph, a one time step is necessary to install the
"matplotlib" package:
```
sudo apt-get update
sudo apt-get install python-matplotlib
```
Then graphs can be produced with:
```
~/klipper/scripts/graphstats.py /tmp/klippy.log loadgraph.png
```
One can then view the resulting **loadgraph.png** file.

88
docs/Features.md Normal file
View File

@@ -0,0 +1,88 @@
Klipper has several compelling features:
* High precision stepper movement. Klipper utilizes an application
processor (such as a low-cost Raspberry Pi) when calculating printer
movements. The application processor determines when to step each
stepper motor, it compresses those events, transmits them to the
micro-controller, and then the micro-controller executes each event
at the requested time. Each stepper event is scheduled with a
precision of 25 micro-seconds or better. The software does not use
kinematic estimations (such as the Bresenham algorithm) - instead it
calculates precise step times based on the physics of acceleration
and the physics of the machine kinematics. More precise stepper
movement translates to quieter and more stable printer operation.
* Best in class performance. Klipper is able to achieve high stepping
rates on both new and old micro-controllers. Even an old 8bit AVR
micro-controller can obtain rates over 175K steps per second. On
more recent ARM micro-controllers, rates over 450K steps per second
are possible. Higher stepper rates enable higher print
velocities. The stepper event timing remains precise even at high
speeds which improves overall stability.
* Configuration via simple config file. There's no need to reflash the
micro-controller to change a setting. All of Klipper's configuration
is stored in a standard config file which can be easily edited. This
makes it easier to setup and maintain the hardware.
* Portable code. Klipper works on both ARM and AVR
micro-controllers. Existing "reprap" style printers can run Klipper
without hardware modification - just add a Raspberry Pi. Klipper's
internal code layout makes it easier to support other
micro-controller architectures as well.
* Simpler code. Klipper uses a very high level language (Python) for
most code. The kinematics algorithms, the G-code parsing, the
heating and thermistor algorithms, etc. are all written in
Python. This makes it easier to develop new functionality.
* Advanced features:
* Klipper implements the "pressure advance" algorithm for
extruders. When properly tuned, pressure advance reduces extruder
ooze.
* Klipper also implements a novel "stepper phase endstop" algorithm
that can dramatically improve the accuracy of typical endstop
switches. When properly tuned it can improve a print's first layer
bed adhesion.
* Support for limiting the top speed of short "zigzag" moves to
reduce printer vibration and noise. See the
[kinematics](Kinematics.md) document for more information.
To get started with Klipper, read the [installation](Installation.md)
guide.
Common features supported by Klipper
====================================
Klipper supports many standard 3d printer features:
* Works with Octoprint. This allows the printer to be controlled using
a regular web-browser. The same Raspberry Pi that runs Klipper can
also run Octoprint.
* Standard G-Code support. Common g-code commands that are produced by
typical "slicers" are supported. One may continue to use Slic3r,
Cura, etc. with Klipper.
* Constant speed acceleration support. All printer moves will
gradually accelerate from standstill to cruising speed and then
decelerate back to a standstill.
* "Look-ahead" support. The incoming stream of G-Code movement
commands are queued and analyzed - the acceleration between
movements in a similar direction will be optimized to reduce print
stalls and improve overall print time.
* Support for cartesian, delta, and corexy style printers.
Step Benchmarks
===============
Below are the results of stepper performance tests. The numbers shown
represent total number of steps per second on the micro-controller.
| Micro-controller | 1 stepper active | 3 steppers active |
| ----------------- | ---------------- | ----------------- |
| 20Mhz AVR | 177K | 117K |
| 16Mhz AVR | 140K | 93K |
| Arduino Due (ARM) | 462K | 406K |

121
docs/Installation.md Normal file
View File

@@ -0,0 +1,121 @@
These instructions assume the software will run on a Raspberry Pi
computer in conjunction with OctoPrint. It is recommended that a
Raspberry Pi 2 or Raspberry Pi 3 computer be used as the host
machine.
It should be possible to run the Klipper host software on any computer
running a recent Linux distribution, but doing so will require Linux
admin knowledge to translate these installation instructions to the
particulars of that machine.
Klipper currently supports Atmel ATmega based micro-controllers and
Arduino Due (Atmel SAM3x8e ARM micro-controller) printers.
Prepping an OS image
====================
Start by installing [OctoPi](https://github.com/guysoft/OctoPi) on the
Raspberry Pi computer. Use OctoPi v0.13.0 or later - see the
[octopi releases](https://github.com/guysoft/OctoPi/releases) for
release information. One should verify that OctoPi boots and that the
OctoPrint web server works. After connecting to the OctoPrint web
page, follow the prompt to upgrade OctoPrint to v1.3.2 or later.
After installing OctoPi and upgrading OctoPrint, ssh into the target
machine (ssh pi@octopi -- password is "raspberry") and run the
following commands:
```
git clone https://github.com/KevinOConnor/klipper
./klipper/scripts/install-octopi.sh
```
The above will download Klipper, install some system dependencies,
setup Klipper to run at system startup, and start the Klipper host
software. It will require an internet connection and it may take a few
minutes to complete.
Building and flashing the micro-controller
==========================================
To compile the micro-controller code, start by configuring it:
```
cd ~/klipper/
make menuconfig
```
Select the appropriate micro-controller and serial baud rate. Once
configured, run:
```
make
```
Finally, for common micro-controllers, the code can be flashed with:
```
sudo service klipper stop
make flash FLASH_DEVICE=/dev/ttyACM0
sudo service klipper start
```
Configuring Klipper
===================
The Klipper configuration is stored in a text file on the Raspberry
Pi. Take a look at the example config files in the
[config directory](../config/). The
[example.cfg](../config/example.cfg) file contains documentation on
command parameters and it can also be used as an initial config file
template. However, for most printers, one of the other config files
may be a more concise starting point. The next step is to copy and
edit one of these config files - for example:
```
cp ~/klipper/config/example.cfg ~/printer.cfg
nano ~/printer.cfg
```
Make sure to review and update each setting that is appropriate for
the hardware.
Configuring OctoPrint to use Klipper
====================================
The OctoPrint web server needs to be configured to communicate with
the Klipper host software. Using a web browser, login to the OctoPrint
web page, and navigate to the Settings tab. Then configure the
following items:
Under "Serial Connection" in "Additional serial ports" add
"/tmp/printer". Then click "Save".
Enter the Settings tab again and under "Serial Connection" change the
"Serial Port" setting to "/tmp/printer". Unselect the "Not only cancel
ongoing prints but also disconnect..." checkbox. Click "Save".
From the main page, under the "Connection" section (at the top left of
the page) make sure the "Serial Port" is set to "/tmp/printer" and
click "Connect". (If "/tmp/printer" is not an available selection then
try reloading the page.)
Once connected, navigate to the "Terminal" tab and type "status"
(without the quotes) into the command entry box and click "Send". The
terminal window will likely report there is an error opening the
config file - issue a "restart" command in the OctoPrint terminal to
load the config. A "status" command will report the printer is ready
if the Klipper config file is successfully read and the
micro-controller is successfully found and configured. It is not
unusual to have configuration errors during the initial setup - update
the printer config file and issue "restart" until "status" reports the
printer is ready.
Klipper reports error messages via the OctoPrint terminal tab. The
"status" command can be used to re-report error messages. The default
Klipper startup script also places a log in **/tmp/klippy.log** which
provides more detailed information.
In addition to common g-code commands, Klipper supports a few extended
commands - "status" and "restart" are examples of these commands. Use
the "help" command to get a list of other extended commands.

293
docs/Kinematics.md Normal file
View File

@@ -0,0 +1,293 @@
This document provides an overview of how Klipper implements robot
motion (its [kinematics](https://en.wikipedia.org/wiki/Kinematics)).
The contents may be of interest to both developers interested in
working on the Klipper software as well as users interested in better
understanding the mechanics of their machines.
Acceleration
============
Klipper implements a constant acceleration scheme whenever the print
head changes velocity - the velocity is gradually changed to the new
speed instead of suddenly jerking to it. Klipper always enforces
acceleration between the tool head and the print. The filament leaving
the extruder can be quite fragile - rapid jerks and/or extruder flow
changes lead to poor quality and poor bed adhesion. Even when not
extruding, if the print head is at the same level as the print then
rapid jerking of the head can cause disruption of recently deposited
filament. Limiting speed changes of the print head (relative to the
print) reduces risks of disrupting the print.
It is also important to enforce a maximum acceleration of the stepper
motors to ensure they do not skip or put excessive stress on the
machine. Klipper limits the acceleration of each stepper by virtue of
limiting the acceleration of the print head. Enforcing acceleration at
the print head naturally also enforces acceleration at the steppers
that control that print head (the inverse is not always true).
Klipper implements constant acceleration. The key formula for constant
acceleration is:
```
velocity(time) = start_velocity + accel*time
```
Trapezoid generator
===================
Klipper uses a traditional "trapezoid generator" to model the motion
of each move - each move has a start speed, it accelerates to a
cruising speed at constant acceleration, it cruises at a constant
speed, and then decelerates to the end speed using constant
acceleration.
![trapezoid](img/trapezoid.svg.png)
It's called a "trapezoid generator" because a velocity diagram of the
move looks like a trapezoid.
The cruising speed is always greater than or equal to both the start
speed and the end speed. The acceleration phase may be of zero
duration (if the start speed is equal to the cruising speed), the
cruising phase may be of zero duration (if the move immediately starts
decelerating after acceleration), and/or the deceleration phase may be
of zero duration (if the end speed is equal to the cruising speed).
![trapezoids](img/trapezoids.svg.png)
Look-ahead
==========
The "look-ahead" system is used to determine cornering speeds between
moves.
Consider the following two moves contained on an XY plane:
![corner](img/corner.svg.png)
In the above situation it is possible to fully decelerate after the
first move and then fully accelerate at the start of the next move,
but that is not ideal as all that acceleration and deceleration would
greatly increase the print time and the frequent changes in extruder
flow would result in poor print quality.
To solve this, the "look-ahead" mechanism queues multiple incoming
moves and analyzes the angles between moves to determine a reasonable
speed that can be obtained during the "junction" between two moves. If
the next move is nearly in the same direction then the head need only
slow down a little (if at all).
![lookahead](img/lookahead.svg.png)
However, if the next move forms an acute angle (the head is going to
travel in nearly a reverse direction on the next move) then only a
small junction speed is permitted.
![lookahead](img/lookahead-slow.svg.png)
The junction speeds are determined using "approximated centripetal
acceleration". Best
[described by the author](https://onehossshay.wordpress.com/2011/09/24/improving_grbl_cornering_algorithm/).
Klipper implements look-ahead between moves contained in the XY plane
that have similar extruder flow rates. Other moves are relatively rare
and implementing look-ahead between them is unnecessary.
Key formula for look-ahead:
```
end_velocity^2 = start_velocity^2 + 2*accel*move_distance
```
Smoothed look-ahead
-------------------
Klipper also implements a mechanism for smoothing out the motions of
short "zigzag" moves. Consider the following moves:
![zigzag](img/zigzag.svg.png)
In the above, the frequent changes from acceleration to deceleration
can cause the machine to vibrate which causes stress on the machine
and increases the noise. To reduce this, Klipper tracks both regular
move acceleration as well as a virtual "acceleration to deceleration"
rate. Using this system, the top speed of these short "zigzag" moves
are limited to smooth out the printer motion:
![smoothed](img/smoothed.svg.png)
Specifically, the code calculates what the velocity of each move would
be if it were limited to this virtual "acceleration to deceleration"
rate (half the normal acceleration rate by default). In the above
picture the dashed gray lines represent this virtual acceleration rate
for the first move. If a move can not reach its full cruising speed
using this virtual acceleration rate then its top speed is reduced to
the maximum speed it could obtain at this virtual acceleration
rate. For most moves the limit will be at or above the move's existing
limits and no change in behavior is induced. For short zigzag moves,
however, this limit reduces the top speed. Note that it does not
change the actual acceleration within the move - the move continues to
use the normal acceleration scheme up to its adjusted top-speed.
Generating steps
================
Once the look-ahead process completes, the print head movement for the
given move is fully known (time, start position, end position,
velocity at each point) and it is possible to generate the step times
for the move. This process is done within "kinematic classes" in the
Klipper code. Outside of these kinematic classes, everything is
tracked in millimeters, seconds, and in cartesian coordinate space.
It's the task of the kinematic classes to convert from this generic
coordinate system to the hardware specifics of the particular printer.
In general, the code determines each step time by first calculating
where along the line of movement the head would be if a step is
taken. It then calculates what time the head should be at that
position. Determining the time along the line of movement can be done
using the formulas for constant acceleration and constant velocity:
```
time = sqrt(2*distance/accel + (start_velocity/accel)^2) - start_velocity/accel
time = distance/cruise_velocity
```
Cartesian Robots
----------------
Generating steps for cartesian printers is the simplest case. The
movement on each axis is directly related to the movement in cartesian
space.
Delta Robots
------------
To generate step times on Delta printers it is necessary to correlate
the movement in cartesian space with the movement on each stepper
tower.
To simplify the math, for each stepper tower, the code calculates the
location of a "virtual tower" that is along the line of movement.
This virtual tower is chosen at the point where the line of movement
(extended infinitely in both directions) would be closest to the
actual tower.
![delta-tower](img/delta-tower.svg.png)
It is then possible to calculate where the head will be along the line
of movement after each step is taken on the virtual tower.
![virtual-tower](img/virtual-tower.svg.png)
The key formula is Pythagoras's theorem:
```
distance_to_tower^2 = arm_length^2 - tower_height^2
```
One complexity is that if the print head passes the virtual tower
location then the stepper direction must be reversed. In this case
forward steps will be taken at the start of the move and reverse steps
will be taken at the end of the move.
### Delta movements beyond simple XY plane ###
Movement calculation is more complicated if a single move contains
both XY movement and Z movement. These moves are rare, but they must
still be handled correctly. A virtual tower along the line of movement
is still calculated, but in this case the tower is not at a 90 degree
angle relative to the line of movement:
![xy+z-tower](img/xy+z-tower.svg.png)
The code continues to calculate step times using the same general
scheme as delta moves within an XY plane, but the slope of the tower
must also be used in the calculations.
Should the move contain only Z movement (ie, no XY movement at all)
then the same math is used - just in this case the tower is parallel
to the line of movement.
### Stepper motor acceleration limits ###
With delta kinematics it is possible for a move that is accelerating
in cartesian space to require an acceleration on a particular stepper
motor greater than the move's acceleration. This can occur when a
stepper arm is more horizontal than vertical and the line of movement
is near that stepper's tower.
Klipper does enforce a maximum ceiling on stepper acceleration that is
three times the maximum acceleration of a move in cartesian
space. (Similarly, the maximum velocity of the stepper is limited to
three times the maximum move velocity.) In order to enforce this
limit, moves at the extreme edge of the build envelope (where a
stepper arm may be nearly horizontal) will have a lower maximum
acceleration and velocity.
Extruder kinematics
-------------------
Klipper implements extruder motion in its own kinematic class. Since
the timing and speed of each print head movement is fully known for
each move, it's possible to calculate the step times for the extruder
independently from the step time calculations of the print head
movement.
Basic extruder movement is simple to calculate. The step time
generation uses the same constant acceleration and constant velocity
formulas that cartesian robots use.
### Pressure advance ###
Experimentation has shown that it's possible to improve the modeling
of the extruder beyond the basic extruder formula. In the ideal case,
as an extrusion move progresses, the same volume of filament should be
deposited at each point along the move and there should be no volume
extruded after the move. Unfortunately, it's common to find that the
basic extrusion formulas cause too little filament to exit the
extruder at the start of extrusion moves and for excess filament to
extrude after extrusion ends. This is often referred to as "ooze".
![ooze](img/ooze.svg.png)
The "pressure advance" system attempts to account for this by using a
different model for the extruder. Instead of naively believing that
each mm^3 of filament fed into the extruder will result in that amount
of mm^3 immediately exiting the extruder, it uses a model based on
pressure. Pressure increases when filament is pushed into the extruder
(as in [Hooke's law](https://en.wikipedia.org/wiki/Hooke%27s_law)) and
the pressure necessary to extrude is dominated by the flow rate
through the nozzle orifice (as in
[Poiseuille's law](https://en.wikipedia.org/wiki/Poiseuille_law)). The
key idea is that the relationship between filament, pressure, and flow
rate can be modeled using a linear coefficient:
```
extra_filament = pressure_advance_coefficient * extruder_velocity
```
See the [pressure advance](Pressure_Advance.md) document for
information on how to find this pressure advance coefficient.
Once configured, Klipper will push in an additional amount of filament
during acceleration. The higher the desired filament flow rate, the
more filament must be pushed in during acceleration to account for
pressure. During head deceleration the extra filament is retracted
(the extruder will have a negative velocity).
![pressure-advance](img/pressure-advance.svg.png)
One may notice that the pressure advance algorithm can cause the
extruder motor to make sudden velocity changes. This is tolerated
based on the idea that the majority of the inertia in the system is in
changing the extruder pressure. As long as the extruder pressure does
not change rapidly the sudden changes in extruder motor velocity are
tolerated.
One area where sudden velocity changes become problematic is during
small changes in head speed due to cornering.
![pressure-cornering](img/pressure-cornering.svg.png)
To prevent this, the Klipper pressure advance code utilizes the move
look-ahead queue to detect intermittent speed changes. During a
deceleration event the code finds the maximum upcoming head speed
within a configurable time window. The pressure is then only adjusted
to this found maximum. This can greatly reduce (or even completely
eliminate) pressure changes during cornering.

294
docs/MCU_Commands.md Normal file
View File

@@ -0,0 +1,294 @@
This document provides information on the low-level micro-controller
commands that are sent from the Klipper "host" software and processed
by the Klipper micro-controller software. This document is not an
authoritative reference for these commands, nor is it an exclusive
list of all available commands.
This document may be useful for users needing to configure a set of
hardware actions that their printer may require at startup (via the
"custom" field in the printer config file), and it may be useful for
developers wishing to obtain a high-level feel for low-level commands.
See the [protocol](Protocol.md) document for more information on the
format of commands and their transmission. The commands here are
described using their "printf" style syntax - for those unfamiliar
with that format, just note that where a '%...' sequence is seen it
should be replaced with an actual integer. For example, a description
with "count=%c" could be replaced with the text "count=10".
Startup Commands
================
It may be necessary to take certain one-time actions to configure the
micro-controller and its peripherals. This section lists common
commands available for that purpose. Unlike most micro-controller
commands, these commands run as soon as they are received and they do
not require any particular setup.
These commands are most useful in the "custom" block of the "mcu"
section of the printer configuration file. This feature is typically
used to configure the initial settings of LEDs, to configure
micro-stepping pins, to configure a digipot, etc.
Several of these commands will take a "pin=%u" parameter. The
low-level micro-controller software uses integer encodings of the
hardware pin numbers, but to make things more readable the host will
translate human readable pin names (eg, "PA3") to their equivalent
integer encodings. By convention, any parameter named "pin" or that
has a "_pin" suffix will use pin name translation by the
host. Similarly, several commands take time parameters specified in
clock ticks. One can specify a value for these parameters in seconds
using the "TICKS()" macro - for example "cycle_ticks=TICKS(0.001)"
would result in "cycle_ticks=16000" on a micro-controller with a 16Mhz
clock.
Common startup commands:
* `set_digital_out pin=%u value=%c` : This command immediately
configures the given pin as a digital out GPIO and it sets it to
either a low level (value=0) or a high level (value=1). This command
may be useful for configuring the initial value of LEDs and for
configuring the initial value of stepper driver micro-stepping pins.
* `set_pwm_out pin=%u cycle_ticks=%u value=%c` : This command will
immediately configure the given pin to use hardware based
pulse-width-modulation (PWM) with the given number of
cycle_ticks. The "cycle_ticks" is the number of MCU clock ticks each
power on and power off cycle should last. A cycle_ticks value of 1
can be used to request the fastest possible cycle time. The "value"
parameter is between 0 and 255 with 0 indicating a full off state
and 255 indicating a full on state. This command may be useful for
enabling CPU and nozzle cooling fans.
* `send_spi_message pin=%u msg=%*s` : This command can be used to
transmit messages to a serial-peripheral-interface (SPI) component
connected to the micro-controller. It has been used to configure the
startup settings of AD5206 digipots. The 'pin' parameter specifies
the chip select line to use during the transmission. The 'msg'
indicates the binary message to transmit to the given chip.
Low-level micro-controller configuration
========================================
Most commands in the micro-controller require an initial setup before
they can be successfully invoked. This section provides an overview of
the configuration process. This section and the following sections are
likely only of interest to developers interested in the internal
details of Klipper.
When the host first connects to the micro-controller it always starts
by obtaining a data dictionary (see [protocol](Protocol.md) for more
information). After the data dictionary is obtained the host will
check if the micro-controller is in a "configured" state and configure
it if not. Configuration involves the following phases:
* `get_config` : The host starts by checking if the micro-controller
is already configured. The micro-controller responds to this command
with a "config" response message. The micro-controller software
always starts in an unconfigured state at power-on. It remains in
this state until the host completes the configuration processes (by
issuing a finalize_config command). If the micro-controller is
already configured from a previous session (and is configured with
the desired settings) then no further action is needed by the host
and the configuration process ends successfully.
* `allocate_oids count=%c` : This command is issued to inform the
micro-controller of the maximum number of object-ids (oid) that the
host requires. It is only valid to issue this command once. An oid
is an integer identifier allocated to each stepper, each endstop,
and each schedulable gpio pin. The host determines in advance the
number of oids it will require to operate the hardware and passes
this to the micro-controller so that it may allocate sufficient
memory to store a mapping from oid to internal object.
* `config_XXX oid=%c ...` : By convention any command starting with
the "config_" prefix creates a new micro-controller object and
assigns the given oid to it. For example, the config_digital_out
command will configure the specified pin as a digital output GPIO
and create an internal object that the host can use to schedule
changes to the given GPIO. The oid parameter passed into the config
command is selected by the host and must be between zero and the
maximum count supplied in the allocate_oids command. The config
commands may only be run when the micro-controller is not in a
configured state (ie, prior to the host sending finalize_config) and
after the allocate_oids command has been sent.
* `finalize_config crc=%u` : The finalize_config command transitions
the micro-controller from an unconfigured state to a configured
state. The crc parameter passed to the micro-controller is stored
and provided back to the host in "config" response messages. By
convention, the host takes a 32bit CRC of the configuration it will
request and at the start of subsequent communication sessions it
checks that the CRC stored in the micro-controller exactly matches
its desired CRC. If the CRC does not match then the host knows the
micro-controller has not been configured in the state desired by the
host.
Common micro-controller objects
-------------------------------
This section lists some commonly used config commands.
* `config_digital_out oid=%c pin=%u default_value=%c
max_duration=%u` : This command creates an internal micro-controller
object for the given GPIO 'pin'. The pin will be configured in
digital output mode and set to an initial value as specified by
'default_value' (0 for low, 1 for high). Creating a digital_out
object allows the host to schedule GPIO updates for the given pin at
specified times (see the schedule_digital_out command described
below). Should the micro-controller software go into shutdown mode
then all configured digital_out objects will be set back to their
default values. The 'max_duration' parameter is used to implement a
safety check - if it is non-zero then it is the maximum number of
clock ticks that the host may set the given GPIO to a non-default
value without further updates. For example, if the default_value is
zero and the max_duration is 16000 then if the host sets the gpio to
a value of one then it must schedule another update to the gpio pin
(to either zero or one) within 16000 clock ticks. This safety
feature can be used with heater pins to ensure the host does not
enable the heater and then go off-line.
* `config_pwm_out oid=%c pin=%u cycle_ticks=%u default_value=%c
max_duration=%u` : This command creates an internal object for
hardware based PWM pins that the host may schedule updates for. Its
usage is analogous to config_digital_out - see the description of
the 'set_pwm_out' and 'config_digital_out' commands for parameter
description.
* `config_soft_pwm_out oid=%c pin=%u cycle_ticks=%u default_value=%c
max_duration=%u` : This command creates an internal micro-controller
object for software implemented PWM. Unlike hardware pwm pins, a
software pwm object does not require any special hardware support
(other than the ability to configure the pin as a digital output
GPIO). Because the output switching is implemented in the
micro-controller software, it is recommended that the cycle_ticks
parameter correspond to a time of 10ms or greater. See the
description of the 'set_pwm_out' and 'config_digital_out' commands
for parameter description.
* `config_analog_in oid=%c pin=%u` : This command is used to configure
a pin in analog input sampling mode. Once configured, the pin can be
sampled at regular interval using the query_analog_in command (see
below).
* `config_stepper oid=%c step_pin=%c dir_pin=%c min_stop_interval=%u
invert_step=%c` : This command creates an internal stepper
object. The 'step_pin' and 'dir_pin' parameters specify the step and
direction pins respectively; this command will configure them in
digital output mode. The 'invert_step' parameter specifies whether a
step occurs on a rising edge (invert_step=0) or falling edge
(invert_step=1). The 'min_stop_interval' implements a safety
feature - it is checked when the micro-controller finishes all moves
for a stepper - if it is non-zero it specifies the minimum number of
clock ticks since the last step. It is used as a check on the
maximum stepper velocity that a stepper may have before stopping.
* `config_end_stop oid=%c pin=%c pull_up=%c stepper_count=%c` : This
command creates an internal "endstop" object. It is used to specify
the endstop pins and to enable "homing" operations (see the
end_stop_home command below). The command will configure the
specified pin in digital input mode. The 'pull_up' parameter
determines whether hardware provided pullup resistors for the pin
(if available) will be enabled. The 'stepper_count' parameter
specifies the maximum number of steppers that this endstop may need
to halt during a homing operation (see end_stop_home below).
Common commands
===============
This section lists some commonly used run-time commands. It is likely
only of interest to developers looking to gain insight into Klipper.
* `schedule_digital_out oid=%c clock=%u value=%c` : This command will
schedule a change to a digital output GPIO pin at the given clock
time. To use this command a 'config_digital_out' command with the
same 'oid' parameter must have been issued during micro-controller
configuration.
* `schedule_pwm_out oid=%c clock=%u value=%c` : Schedules a change to
a hardware PWM output pin. See the 'schedule_digital_out' and
'config_pwm_out' commands for more info.
* `schedule_soft_pwm_out oid=%c clock=%u value=%c` : Schedules a
change to a software PWM output pin. See the 'schedule_digital_out'
and 'config_soft_pwm_out' commands for more info.
* `query_analog_in oid=%c clock=%u sample_ticks=%u sample_count=%c
rest_ticks=%u min_value=%hu max_value=%hu` : This command sets up a
recurring schedule of analog input samples. To use this command a
'config_analog_in' command with the same 'oid' parameter must have
been issued during micro-controller configuration. The samples will
start as of 'clock' time, it will report on the obtained value every
'rest_ticks' clock ticks, it will over-sample 'sample_count' number
of times, and it will pause 'sample_ticks' number of clock ticks
between over-sample samples. The 'min_value' and 'max_value'
parameters implement a safety feature - the micro-controller
software will verify the sampled value (after any oversampling) is
always between the supplied range. This is intended for use with
pins attached to thermistors controlling heaters - it can be used to
check that a heater is within a temperature range.
* `get_status` : This command causes the micro-controller to generate
a "status" response message. The host sends this command once a
second to obtain the value of the micro-controller clock and to
estimate the drift between host and micro-controller clocks. It
enables the host to accurately estimate the micro-controller clock.
Stepper commands
----------------
* `queue_step oid=%c interval=%u count=%hu add=%hi` : This command
schedules 'count' number of steps for the given stepper, with
'interval' number of clock ticks between each step. The first step
will be 'interval' number of clock ticks since the last scheduled
step for the given stepper. If 'add' is non-zero then the interval
will be adjusted by 'add' amount after each step. This command
appends the given interval/count/add sequence to a per-stepper
queue. There may be hundreds of these sequences queued during normal
operation. New sequence are appended to the end of the queue and as
each sequence completes its 'count' number of steps it is popped
from the front of the queue. This system allows the micro-controller
to queue potentially hundreds of thousands of steps - all with
reliable and predictable schedule times.
* `set_next_step_dir oid=%c dir=%c` : This command specifies the value
of the dir_pin that the next queue_step command will use.
* `reset_step_clock oid=%c clock=%u` : Normally, step timing is
relative to the last step for a given stepper. This command resets
the clock so that the next step is relative to the supplied 'clock'
time. The host usually only sends this command at the start of a
print.
* `stepper_get_position oid=%c` : This command causes the
micro-controller to generate a "stepper_position" response message
with the stepper's current position. The position is the total
number of steps generated with dir=1 minus the total number of steps
generated with dir=0.
* `end_stop_home oid=%c clock=%u rest_ticks=%u pin_value=%c` : This
command is used during stepper "homing" operations. To use this
command a 'config_end_stop' command with the same 'oid' parameter
must have been issued during micro-controller configuration. When
this command is invoked, the micro-controller will sample the
endstop pin every 'rest_ticks' clock ticks and check if it has a
value equal to 'pin_value'. If the value matches then the movement
queue for the associated stepper will be cleared and the stepper
will come to an immediate halt. The host uses this command to
implement homing - the host instructs the endstop to sample for the
endstop trigger and then it issues a series of queue_step commands
to move a stepper towards the endstop. Once the stepper hits the
endstop, the trigger will be detected, the movement halted, and the
host notified.
### Move queue
Each queue_step command utilizes an entry in the micro-controller
"move queue". This queue is allocated when it receives the
"finalize_config" command, and it reports the number of available
queue entries in "config" response messages.
It is the responsibility of the host to ensure that there is available
space in the queue before sending a queue_step command. The host does
this by calculating when each queue_step command completes and
scheduling new queue_step commands accordingly.

37
docs/Overview.md Normal file
View File

@@ -0,0 +1,37 @@
Welcome to the Klipper documentation. There are two parts to Klipper -
code that runs on a micro-controller and code that runs on a "host"
machine. The host code is intended to run on a low-cost
general-purpose machine such as a Raspberry Pi, while the
micro-controller code is intended to run on commodity micro-controller
chips. Read [features](Features.md) for reasons to use Klipper. See
[installation](Installation.md) to get started with Klipper.
The Klipper configuration is stored in a simple text file on the host
machine. The [config/example.cfg](../config/example.cfg) file serves
as a reference for the config file. The
[Pressure Advance](Pressure_Advance.md) document contains information
on tuning the pressure advance config.
The [kinematics](Kinematics.md) document provides some technical
details on how Klipper implements motion.
The history of Klipper releases is available at
[releases](Releases.md).
Developer Documentation
=======================
There are also several documents available for developers interested
in understanding how Klipper works. Start with the
[code overview](Code_Overview.md) document - it provides information
on the structure and layout of the Klipper code.
See [protocol](Protocol.md) for information on the low-level messaging
protocol between host and micro-controller. See also
[MCU commands](MCU_Commands.md) for a description of low-level
commands implemented in the micro-controller software.
See [debugging](Debugging.md) for information on how to test and debug
Klipper.
See [todo](Todo.md) for information on possible future code features.

74
docs/Pressure_Advance.md Normal file
View File

@@ -0,0 +1,74 @@
This document provides information on tuning the "pressure advance"
configuration variables for a particular nozzle and filament. The
pressure advance feature can be helpful in reducing ooze. For more
information on how pressure advance is implemented see the
[kinematics](Kinematics.md) document.
Tuning pressure advance
=======================
Pressure advance does two useful things - it reduces ooze during
non-extrude moves and it reduces blobbing during cornering. This guide
uses the second feature (reducing blobbing during cornering) as a
mechanism for measuring and tuning the pressure advance configuration.
Start by changing the extruder section of the config file so that
pressure_advance is set to 0.0. (Make sure to issue a RESTART command
after each update to the config file so that the new configuration
takes effect.) Then print at least 10 layers of a large hollow square
at high speed (eg, 100mm/s). See
[docs/prints/square.stl](prints/square.stl) file for an STL file that
one may use. While the object is printing, make a note of which
direction the head is moving during external perimeters. What many
people see here is blobbing occurring at the corners - extra filament
at the corner in the direction the head travels followed by a possible
lack of filament on the side immediately after that corner:
![corner-blob](img/corner-blob.jpg)
This blobbing is the result of pressure in the extruder being released
as a blob when the head slows down to corner.
The next step is to set pressure_advance_lookahead_time to 0.0, slowly
increase pressure_advance (eg, start with 0.05), and reprint the test
object. (Be sure to issue RESTART between each config change.) The
goal is to attempt to eliminate the blobbing during cornering. (With
pressure advance, the extruder will retract when the head slows down,
thus countering the pressure buildup and ideally eliminate the
blobbing.) If a test run is done with a pressure_advance setting that
is too high, one typically sees a dimple in the corner followed by
possible blobbing after the corner (too much filament is retracted
during slow down and then too much filament is extruded during the
following speed up after cornering):
![corner-dimple](img/corner-dimple.jpg)
The goal is to find the smallest pressure_advance value that results
in good quality corners:
![corner-good](img/corner-good.jpg)
Typical pressure_advance values are between 0.05 and 0.20 (the high
end usually only with bowden extruders).
Once a good pressure_advance value is found, return
pressure_advance_lookahead_time to its default (0.010). This parameter
controls how far in advance to check if a head slow-down is
immediately followed by a speed-up - it reduces pointless pressure
changes in the head. It's possible to tune this - higher values will
decrease the number of pressure changes in the nozzle at the expense
of permitting more blobbing during cornering. (Tuning this value is
unlikely to impact ooze.) The default of 10ms should work well on most
printers.
Although this tuning exercise directly improves the quality of
corners, it's worth remembering that a good pressure advance
configuration can reduce ooze throughout the print.
Finally, once pressure_advance is tuned in Klipper, it may still be
useful to configure a small retract value in the slicer (eg, 0.75mm)
and to utilize the slicer's "wipe on retract option" if available.
These slicer settings may help counteract ooze caused by filament
cohesion (filament pulled out of the nozzle due to the stickiness of
the plastic). It is recommended to disable the slicer's "z-lift on
retract" option.

343
docs/Protocol.md Normal file
View File

@@ -0,0 +1,343 @@
The Klipper messaging protocol is used for low-level communication
between the Klipper host software and the Klipper micro-controller
software. At a high level the protocol can be thought of as a series
of command and response strings that are compressed, transmitted, and
then processed at the receiving side. An example series of commands in
uncompressed human-readable format might look like:
```
set_digital_out pin=86 value=1
set_digital_out pin=85 value=1
schedule_digital_out oid=8 clock=4000000 value=0
queue_step oid=7 interval=7458 count=10 add=331
queue_step oid=7 interval=11717 count=4 add=1281
```
See the [mcu commands](MCU_Commands.md) document for information on
available commands. See the [debugging](Debugging.md) document for
information on how to translate a G-Code file into its corresponding
human-readable micro-controller commands.
This page provides a high-level description of the Klipper messaging
protocol itself. It describes how messages are declared, encoded in
binary format (the "compression" scheme), and transmitted.
The goal of the protocol is to enable an error-free communication
channel between the host and micro-controller that is low-latency,
low-bandwidth, and low-complexity for the micro-controller.
Micro-controller Interface
==========================
The Klipper transmission protocol can be thought of as a
[RPC](https://en.wikipedia.org/wiki/Remote_procedure_call) mechanism
between micro-controller and host. The micro-controller software
declares the commands that the host may invoke along with the response
messages that it can generate. The host uses that information to
command the micro-controller to perform actions and to interpret the
results.
Declaring commands
------------------
The micro-controller software declares a "command" by using the
DECL_COMMAND() macro in the C code. For example:
```
DECL_COMMAND(command_set_digital_out, "set_digital_out pin=%u value=%c");
```
The above declares a command named "set_digital_out". This allows the
host to "invoke" this command which would cause the
command_set_digital_out() C function to be executed in the
micro-controller. The above also indicates that the command takes two
integer parameters. When the command_set_digital_out() C code is
executed, it will be passed an array containing these two integers -
the first corresponding to the 'pin' and the second corresponding to
the 'value'.
In general, the parameters are described with printf() style syntax
(eg, "%u"). The formatting directly corresponds to the human-readable
view of commands (eg, "set_digital_out pin=86 value=1"). In the above
example, "value=" is a parameter name and "%c" indicates the parameter
is an integer. Internally, the parameter name is only used as
documentation. In this example, the "%c" is also used as documentation
to indicate the expected integer is 1 byte in size (the declared
integer size does not impact the parsing or encoding).
The micro-controller build will collect all commands declared with
DECL_COMMAND(), determine their parameters, and arrange for them to be
callable.
Declaring responses
-------------------
To send information from the micro-controller to the host a "response"
is generated. These are both declared and transmitted using the
sendf() C macro. For example:
```
sendf("status clock=%u status=%c", sched_read_time(), sched_is_shutdown());
```
The above transmits a "status" response message that contains two
integer parameters ("clock" and "status"). The micro-controller build
automatically finds all sendf() calls and generates encoders for
them. The first parameter of the sendf() function describes the
response and it is in the same format as command declarations.
The host can arrange to register a callback function for each
response. So, in effect, commands allow the host to invoke C functions
in the micro-controller and responses allow the micro-controller
software to invoke code in the host.
The sendf() macro should only be invoked from command or task
handlers, and it should not be invoked from interrupts or timers. The
code does not need to issue a sendf() in response to a received
command, it is not limited in the number of times sendf() may be
invoked, and it may invoke sendf() at any time from a task handler.
### Output responses
To simplify debugging, there is also has an output() C function. For
example:
```
output("The value of %u is %s with size %u.", x, buf, buf_len);
```
The output() function is similar in usage to printf() - it is intended
to generate and format arbitrary messages for human consumption.
Declaring constants
-------------------
Constants can also be exported. For example, the following:
```
DECL_CONSTANT(SERIAL_BAUD, 250000);
```
would export a constant named "SERIAL_BAUD" with a value of 250000
from the micro-controller to the host.
Low-level message encoding
==========================
To accomplish the above RPC mechanism, each command and response is
encoded into a binary format for transmission. This section describes
the transmission system.
Message Blocks
--------------
All data sent from host to micro-controller and vice-versa are
contained in "message blocks". A message block has a two byte header
and a three byte trailer. The format of a message block is:
```
<1 byte length><1 byte sequence><n-byte content><2 byte crc><1 byte sync>
```
The length byte contains the number of bytes in the message block
including the header and trailer bytes (thus the minimum message
length is 5 bytes). The maximum message block length is currently 64
bytes. The sequence byte contains a 4 bit sequence number in the
low-order bits and the high-order bits always contain 0x10 (the
high-order bits are reserved for future use). The content bytes
contain arbitrary data and its format is described in the following
section. The crc bytes contain a 16bit CCITT
[CRC](https://en.wikipedia.org/wiki/Cyclic_redundancy_check) of the
message block including the header bytes but excluding the trailer
bytes. The sync byte is 0x7e.
The format of the message block is inspired by
[HDLC](https://en.wikipedia.org/wiki/High-Level_Data_Link_Control)
message frames. Like in HDLC, the message block may optionally contain
an additional sync character at the start of the block. Unlike in
HDLC, a sync character is not exclusive to the framing and may be
present in the message block content.
Message Block Contents
----------------------
Each message block sent from host to micro-controller contains a
series of zero or more message commands in its contents. Each command
starts with a [Variable Length Quantity](#variable-length-quantities)
(VLQ) encoded integer command-id followed by zero or more VLQ
parameters for the given command.
As an example, the following four commands might be placed in a single
message block:
```
set_digital_out pin=86 value=1
set_digital_out pin=85 value=0
get_config
get_status
```
and encoded into the following eight VLQ integers:
```
<id_set_digital_out><86><1><id_set_digital_out><85><0><id_get_config><id_get_status>
```
In order to encode and parse the message contents, both the host and
micro-controller must agree on the command ids and the number of
parameters each command has. So, in the above example, both the host
and micro-controller would know that "id_set_digital_out" is always
followed by two parameters, and "id_get_config" and "id_get_status"
have zero parameters. The host and micro-controller share a "data
dictionary" that maps the command descriptions (eg, "set_digital_out
pin=%u value=%c") to their integer command-ids. When processing the
data, the parser will know to expect a specific number of VLQ encoded
parameters following a given command id.
The message contents for blocks sent from micro-controller to host
follow the same format. The identifiers in these messages are
"response ids", but they serve the same purpose and follow the same
encoding rules. In practice, message blocks sent from the
micro-controller to the host never contain more than one response in
the message block contents.
### Variable Length Quantities
See the [wikipedia article](https://en.wikipedia.org/wiki/Variable-length_quantity)
for more information on the general format of VLQ encoded
integers. Klipper uses an encoding scheme that supports both positive
and negative integers. Integers close to zero use less bytes to encode
and positive integers typically encode using less bytes than negative
integers. The following table shows the number of bytes each integer
takes to encode:
| Integer | Encoded size |
|---------------------------|--------------|
| -32 .. 95 | 1 |
| -4096 .. 12287 | 2 |
| -524288 .. 1572863 | 3 |
| -67108864 .. 201326591 | 4 |
| -2147483648 .. 4294967295 | 5 |
### Variable length strings
As an exception to the above encoding rules, if a parameter to a
command or response is a dynamic string then the parameter is not
encoded as a simple VLQ integer. Instead it is encoded by transmitting
the length as a VLQ encoded integer followed by the contents itself:
```
<VLQ encoded length><n-byte contents>
```
The command descriptions found in the data dictionary allow both the
host and micro-controller to know which command parameters use simple
VLQ encoding and which parameters use string encoding.
Data Dictionary
===============
In order for meaningful communications to be established between
micro-controller and host, both sides must agree on a "data
dictionary". This data dictionary contains the integer identifiers for
commands and responses along with their descriptions.
The micro-controller build uses the contents of DECL_COMMAND() and
sendf() macros to generate the data dictionary. The build
automatically assigns unique identifiers to each command and
response. This system allows both the host and micro-controller code
to seamlessly use descriptive human-readable names while still using
minimal bandwidth.
The host queries the data dictionary when it first connects to the
micro-controller. Once the host downloads the data dictionary from the
micro-controller, it uses that data dictionary to encode all commands
and to parse all responses from the micro-controller. The host must
therefore handle a dynamic data dictionary. However, to keep the
micro-controller software simple, the micro-controller always uses its
static (compiled in) data dictionary.
The data dictionary is queried by sending "identify" commands to the
micro-controller. The micro-controller will respond to each identify
command with an "identify_response" message. Since these two commands
are needed prior to obtaining the data dictionary, their integer ids
and parameter types are hard-coded in both the micro-controller and
the host. The "identify_response" response id is 0, the "identify"
command id is 1. Other than having hard-coded ids the identify command
and its response are declared and transmitted the same way as other
commands and responses. No other command or response is hard-coded.
The format of the transmitted data dictionary itself is a zlib
compressed JSON string. The micro-controller build process generates
the string, compresses it, and stores it in the text section of the
micro-controller flash. The data dictionary can be much larger than
the maximum message block size - the host downloads it by sending
multiple identify commands requesting progressive chunks of the data
dictionary. Once all chunks are obtained the host will assemble the
chunks, uncompress the data, and parse the contents.
In addition to information on the communication protocol, the data
dictionary also contains the software version, constants (as defined
by DECL_CONSTANT), and static strings.
Static Strings
--------------
To reduce bandwidth the data dictionary also contains a set of static
strings known to the micro-controller. This is useful when sending
messages from micro-controller to host. For example, if the
micro-controller were to run:
```
shutdown("Unable to handle command");
```
The error message would be encoded and sent using a single VLQ. The
host uses the data dictionary to resolve VLQ encoded static string ids
to their associated human-readable strings.
Message flow
============
Message commands sent from host to micro-controller are intended to be
error-free. The micro-controller will check the CRC and sequence
numbers in each message block to ensure the commands are accurate and
in-order. The micro-controller always processes message blocks
in-order - should it receive a block out-of-order it will discard it
and any other out-of-order blocks until it receives blocks with the
correct sequencing.
The low-level host code implements an automatic retransmission system
for lost and corrupt message blocks sent to the micro-controller. To
facilitate this, the micro-controller transmits an "ack message block"
after each successfully received message block. The host schedules a
timeout after sending each block and it will retransmit should the
timeout expire without receiving a corresponding "ack". In addition,
if the micro-controller detects a corrupt or out-of-order block it may
transmit a "nak message block" to facilitate fast retransmission.
An "ack" is a message block with empty content (ie, a 5 byte message
block) and a sequence number greater than the last received host
sequence number. A "nak" is a message block with empty content and a
sequence number less than the last received host sequence number.
The protocol facilitates a "window" transmission system so that the
host can have many outstanding message blocks in-flight at a
time. (This is in addition to the many commands that may be present in
a given message block.) This allows maximum bandwidth utilization even
in the event of transmission latency. The timeout, retransmit,
windowing, and ack mechanism are inspired by similar mechanisms in
[TCP](https://en.wikipedia.org/wiki/Transmission_Control_Protocol).
In the other direction, message blocks sent from micro-controller to
host are designed to be error-free, but they do not have assured
transmission. (Responses should not be corrupt, but they may go
missing.) This is done to keep the implementation in the
micro-controller simple. There is no automatic retransmission system
for responses - the high-level code is expected to be capable of
handling an occasional missing response (usually by re-requesting the
content or setting up a recurring schedule of response
transmission). The sequence number field in message blocks sent to the
host is always one greater than the last received sequence number of
message blocks received from the host. It is not used to track
sequences of response message blocks.

2
docs/README.md Normal file
View File

@@ -0,0 +1,2 @@
Welcome to the Klipper documentation. The
[overview document](Overview.md) is a good starting point.

58
docs/Releases.md Normal file
View File

@@ -0,0 +1,58 @@
History of Klipper releases. Please see
[installation](Installation.md) for information on installing Klipper.
Klipper 0.4.0
=============
Available on 20170503. Major changes in this release:
* Improved installation on Raspberry Pi machines. Most of the install
is now scripted.
* Support for corexy kinematics
* Documentation updates: New Kinematics document, new Pressure Advance
tuning guide, new example config files, and more
* Stepper performance improvements (20Mhz AVRs over 175K steps per
second, Arduino Due over 460K)
* Support for automatic micro-controller resets. Support for resets
via toggling USB power on Raspberry Pi.
* The pressure advance algorithm now works with look-ahead to reduce
pressure changes during cornering.
* Support for limiting the top speed of short zigzag moves
* Support for AD595 sensors
* Several bug fixes and code cleanups
Klipper 0.3.0
=============
Available on 20161223. Major changes in this release:
* Improved documentation
* Support for robots with delta kinematics
* Support for Arduino Due micro-controller (ARM cortex-M3)
* Support for USB based AVR micro-controllers
* Support for "pressure advance" algorithm - it reduces ooze during
prints.
* New "stepper phased based endstop" feature - enables higher
precision on endstop homing.
* Support for "extended g-code" commands such as "help", "restart",
and "status".
* Support for reloading the Klipper config and restarting the host
software by issuing a "restart" command from the terminal.
* Stepper performance improvements (20Mhz AVRs up to 158K steps per
second).
* Improved error reporting. Most errors now shown via the terminal
along with help on how to resolve.
* Several bug fixes and code cleanups
Klipper 0.2.0
=============
Initial release of Klipper. Available on 20160525. Major features
available in the initial release include:
* Basic support for cartesian printers (steppers, extruder, heated
bed, cooling fan).
* Support for common g-code commands. Support for interfacing with
OctoPrint.
* Acceleration and lookahead handling
* Support for AVR micro-controllers via standard serial ports

103
docs/Todo.md Normal file
View File

@@ -0,0 +1,103 @@
There are several features still to be implemented in Klipper. In no
particular order:
Host user interaction
=====================
* See if there is a better way to report errors. Octoprint sometimes
doesn't highlight an error (one has to look in the terminal tab to
find the error) and errors written to the log can be non-obvious to
a user.
* Improve gcode interface:
* Provide a better way to handle print nozzle z offsets. The M206
command is cryptic to use and it is too easy to set the value
incorrectly or to forget to set it.
* Provide a way to temporarily disable endstop checks so that a user
can issue commands that potentially move the head past
position_min/position_max.
* Improve logging:
* Possibly collate and report the statistics messages in the log in a
more friendly way.
* Possibly support a mechanism for the host to limit maximum velocity
so that the mcu is never requested to step at a higher rate than it
can support.
Safety features
===============
* Support loading a valid step range into the micro-controller
software after homing. This would provide a sanity check in the
micro-controller that would reduce the risk of the host commanding a
stepper motor past its valid step range. To maintain high
efficiency, the micro-controller would only need to check
periodically (eg, every 100ms) that the stepper is in range.
* Possibly support periodically querying the endstop switches and use
multiple step ranges depending on the switch state. This would
enable runtime endstop detection. (However, it's unclear if runtime
endstop detection is a good idea because of spurious signals caused
by electrical noise.)
* Support validating that heaters are heating at expected rates. This
can be useful to detect a sensor failure (eg, thermistor short) that
could otherwise cause the PID to command excessive heating.
Testing features
================
* Complete the host based simulator. It's possible to compile the
micro-controller for a "host simulator", but that simulator doesn't
do anything currently. It would be useful to expand the code to
support more error checks, kinematic simulations, and improved
logging.
Documentation
=============
* Document and test running the host software on a Beagle Bone Black.
* Add documentation describing how to perform bed-leveling accurately
in Klipper. Improve description of stepper phase based bed leveling.
Hardware features
=================
* Port to additional micro-controller architectures:
* Beagle Bone Black PRU
* Smoothieboard / NXP LPC1769 (ARM cortex-M3)
* Unix based scheduling; Unix based real-time scheduling
* Support for additional kinematics: scara, etc.
* Support shared motor enable GPIO lines.
* Support for multiple extruders.
* Support for bed-level probes.
* Possible support for touch panels attached to the micro-controller.
(In general, it would be preferable to attach touch panels to the
host system and have octoprint interact with the panel directly, but
it would also be useful to handle panels already hardwired to the
micro-controller.)
* Possibly support printers using multiple micro-controllers.
Misc features
=============
* Possibly use cubic functions instead of quadratic functions in step
compression code.
* Possibly support a "feed forward PID" that takes into account the
amount of plastic being extruded. If the extrude rate changes
significantly during a print it can cause heating bumps that the PID
overcompensates for. The temperature change due to the extrusion
rate could be modeled to eliminate these bumps and make the
extrusion temperature more consistent.

BIN
docs/img/corner-blob.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
docs/img/corner-dimple.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
docs/img/corner-good.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

184
docs/img/corner.svg Normal file
View File

@@ -0,0 +1,184 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="54.904114mm"
height="6.0860338mm"
viewBox="0 0 194.54213 21.564687"
id="svg3506"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="corner.svg">
<defs
id="defs3508">
<marker
inkscape:stockid="DiamondL"
orient="auto"
refY="0"
refX="0"
id="DiamondL"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path4399"
d="M 0,-7.0710768 -7.0710894,0 0,7.0710589 7.0710462,0 0,-7.0710768 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="scale(0.8,0.8)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0"
refX="0"
id="Arrow2Lend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path4341"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="marker4596"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path4598"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.4,0,0,-0.4,-4,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path4329"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.4,0,0,-0.4,-4,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend-1"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path4329-1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.49"
inkscape:cx="95.030833"
inkscape:cy="-0.17370789"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showborder="false"
inkscape:window-width="1068"
inkscape:window-height="478"
inkscape:window-x="378"
inkscape:window-y="113"
inkscape:window-maximized="0">
<inkscape:grid
type="xygrid"
id="grid6021"
spacingx="9.9999997"
spacingy="10.000001"
originx="0.89299989"
originy="-30.954583" />
</sodipodi:namedview>
<metadata
id="metadata3511">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-253.40821,-436.43703)">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="m 345.38554,440.31401 96.88541,12.96764"
id="path3514"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend-1)"
d="m 253.63788,454.62572 89.78715,-13.91164"
id="path3514-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.25000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="189.09824"
y="482.48389"
id="text12656-9"
sodipodi:linespacing="125%"
transform="matrix(0.98759291,-0.15703579,0.15703579,0.98759291,0,0)"
inkscape:transform-center-x="1.3563414"
inkscape:transform-center-y="-5.7099754"><tspan
sodipodi:role="line"
id="tspan5552"
x="189.09824"
y="482.48389">move 1</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.25000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="427.95532"
y="379.5321"
id="text12656-9-8"
sodipodi:linespacing="125%"
transform="matrix(0.98949457,0.14457001,-0.14457001,0.98949457,0,0)"><tspan
sodipodi:role="line"
id="tspan5554"
x="427.95532"
y="379.5321">move 2</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
docs/img/corner.svg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

273
docs/img/delta-tower.svg Normal file
View File

@@ -0,0 +1,273 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="97.22496mm"
height="32.550285mm"
viewBox="0 0 344.49789 115.33566"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="delta-tower.svg">
<defs
id="defs4">
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker6618"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Mend">
<path
transform="matrix(-0.4,0,0,-0.4,-4,0)"
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
id="path6620"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0.0"
refX="0.0"
id="marker6500"
style="overflow:visible;"
inkscape:isstock="true">
<path
id="path6502"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1;fill:#4b4b4b;fill-opacity:1"
transform="scale(0.4) rotate(180) translate(10,0)" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible;"
id="marker6082"
refX="0.0"
refY="0.0"
orient="auto"
inkscape:stockid="Arrow1Mend"
inkscape:collect="always">
<path
transform="scale(0.4) rotate(180) translate(10,0)"
style="fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1;fill:#4b4b4b;fill-opacity:1"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
id="path6084" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Mend"
style="overflow:visible;"
inkscape:isstock="true"
inkscape:collect="always">
<path
id="path5747"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1;fill:#4b4b4b;fill-opacity:1"
transform="scale(0.4) rotate(180) translate(10,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mstart"
orient="auto"
refY="0.0"
refX="0.0"
id="Arrow1Mstart"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path5744"
d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
style="fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1;fill:#4b4b4b;fill-opacity:1"
transform="scale(0.4) translate(10,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend-1"
style="overflow:visible"
inkscape:isstock="true"
inkscape:collect="always">
<path
inkscape:connector-curvature="0"
id="path4329-1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker6082-9"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Mend"
inkscape:collect="always">
<path
inkscape:connector-curvature="0"
transform="matrix(-0.4,0,0,-0.4,-4,0)"
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
id="path6084-2" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.75"
inkscape:cx="172.24895"
inkscape:cy="45.708959"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="928"
inkscape:window-height="628"
inkscape:window-x="162"
inkscape:window-y="50"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showborder="false"
inkscape:snap-global="false"
showguides="false">
<inkscape:grid
type="xygrid"
id="grid3436" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-135.22429,-249.96955)">
<ellipse
style="fill:#4d4d4d;stroke:#4b4b4b;stroke-width:1;stroke-miterlimit:4;stroke-dasharray:2, 1, 0.5, 1;stroke-dashoffset:0;stroke-opacity:1"
id="path4255"
cx="353.79568"
cy="327.87662"
rx="4.2857141"
ry="4.8571429" />
<path
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000006;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
d="M 181.50998,381.87664 359.22427,275.01949"
id="path5510"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="371.22427"
y="354.44806"
id="text6058"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan6060"
x="371.22427"
y="354.44806">stepper</tspan><tspan
sodipodi:role="line"
x="371.22427"
y="366.94806"
id="tspan9337">tower</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="166.65283"
y="304.16235"
id="text6062"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan6064"
x="166.65283"
y="304.16235">line of movement</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:10.0000006px;line-height:125%;font-family:'DejaVu Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;-inkscape-font-specification:'DejaVu Sans, Normal';font-stretch:normal;font-variant:normal;text-anchor:start;text-align:start;writing-mode:lr;"
x="252.93855"
y="384.16235"
id="text6066"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan6068"
x="252.93855"
y="384.16235">move</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000006;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;marker-end:url(#marker6618)"
d="m 382.65284,344.73378 c -0.19273,-13.52091 -9.87887,-14.83602 -20.57143,-14.85715"
id="path6070"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker6500)"
d="m 254.65284,374.44806 c 3.39239,-12.86009 -2.06023,-20.09154 -15.42857,-22.28571"
id="path6072"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker6082)"
d="m 257.50997,296.16234 c 31.05376,-3.13332 32.38959,-1.23784 42.28572,10.28572"
id="path6074"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend-1)"
d="m 219.61431,358.80126 57.78715,-34.48307"
id="path3514-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:0.50000003;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 351.22427,323.59092 -20.57143,-32"
id="path3358"
inkscape:connector-curvature="0" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="244.36713"
y="257.30521"
id="text4460"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4462"
x="244.36713"
y="257.30521">virtual tower</tspan><tspan
sodipodi:role="line"
x="244.36713"
y="269.80521"
id="tspan5867">location</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker6082-9)"
d="m 310.90661,257.14111 c 21.29088,8.40268 18.35244,16.28958 20.57143,29.7143"
id="path6074-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

208
docs/img/lookahead-slow.svg Normal file
View File

@@ -0,0 +1,208 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="97.22496mm"
height="32.550285mm"
viewBox="0 0 344.49789 115.33566"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="lookahead-slow.svg"
inkscape:export-filename="/home/kevin/src/reprap/firmware/klipper/docs/img/lookahead-slow.svg.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend-1"
style="overflow:visible"
inkscape:isstock="true">
<path
inkscape:connector-curvature="0"
id="path4329-1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path4329"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.4,0,0,-0.4,-4,0)"
inkscape:connector-curvature="0" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.15"
inkscape:cx="3.4198125"
inkscape:cy="101.26451"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1091"
inkscape:window-height="588"
inkscape:window-x="149"
inkscape:window-y="422"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showborder="false"
inkscape:snap-global="false"
showguides="false">
<inkscape:grid
type="xygrid"
id="grid3436" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-135.22429,-249.96955)">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 1.06383,102.12765 327.12765,-0.53192 -7.97871,5.85107"
id="path3347"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.5px;line-height:100%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="434.04257"
y="365.1282"
id="text3349"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan3351"
x="434.04257"
y="365.1282">time</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.5px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-313.86618"
y="140.27856"
id="text3353"
sodipodi:linespacing="125%"
transform="matrix(-0.01601372,-0.99987177,0.99987177,-0.01601372,0,0)"><tspan
sodipodi:role="line"
id="tspan3355"
x="-313.86618"
y="140.27856">velocity</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 -5.31915,8.51063"
id="path3359"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.62366331px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 179.63013,351.45141 16.05677,-60.94328 43.25999,0 16.53759,47.11348"
id="path3361"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.7558428px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 254.72406,337.27551 22.65101,-77.77178 43.89917,0 24.69858,91.73948"
id="path3361-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.25000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="195.45749"
y="286.52051"
id="text12656-9"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan7078"
x="195.45749"
y="286.52051">move A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.25000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="280.5639"
y="254.60564"
id="text12656-9-3"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan7080"
x="280.5639"
y="254.60564">move B</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend)"
d="m 74.333855,283.02668 -147.83244,52.19984"
id="path3514"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend-1)"
d="m -79.633985,251.6122 154.13499,31.81455"
id="path3514-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.25000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="36.7374"
y="252.31848"
id="text12656-9-1"
sodipodi:linespacing="125%"
transform="matrix(0.96753827,0.25272454,-0.25272454,0.96753827,0,0)"
inkscape:transform-center-x="-0.91382951"
inkscape:transform-center-y="-4.9145266"><tspan
sodipodi:role="line"
id="tspan7074"
x="36.7374"
y="252.31848">move A</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.25000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-126.26086"
y="304.35226"
id="text12656-9-8"
sodipodi:linespacing="125%"
transform="matrix(0.93839918,-0.34555314,0.34555314,0.93839918,0,0)"><tspan
sodipodi:role="line"
id="tspan7076"
x="-126.26086"
y="304.35226">move B</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

136
docs/img/lookahead.svg Normal file
View File

@@ -0,0 +1,136 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="97.22496mm"
height="32.550285mm"
viewBox="0 0 344.49789 115.33566"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="lookahead.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.94"
inkscape:cx="116.54041"
inkscape:cy="45.708959"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1091"
inkscape:window-height="588"
inkscape:window-x="149"
inkscape:window-y="422"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showborder="false"
inkscape:snap-global="false"
showguides="false">
<inkscape:grid
type="xygrid"
id="grid3436" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-135.22429,-249.96955)">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 1.06383,102.12765 327.12765,-0.53192 -7.97871,5.85107"
id="path3347"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.5px;line-height:100%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="434.04257"
y="365.1282"
id="text3349"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan3351"
x="434.04257"
y="365.1282">time</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.5px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-313.86618"
y="140.27856"
id="text3353"
sodipodi:linespacing="125%"
transform="matrix(-0.01601372,-0.99987177,0.99987177,-0.01601372,0,0)"><tspan
sodipodi:role="line"
id="tspan3355"
x="-313.86618"
y="140.27856">velocity</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 -5.31915,8.51063"
id="path3359"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.62366331px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 179.63013,351.45141 16.05677,-60.94328 61.3451,0 4.83546,8.81561"
id="path3361"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.7558428px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 261.70791,300.17937 13.5395,-40.67564 59.85662,0 24.69858,91.73948"
id="path3361-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.25000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="200.77664"
y="286.52051"
id="text12656-9"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5532"
x="200.77664"
y="286.52051">move 1</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.25000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="280.5639"
y="255.66946"
id="text12656-9-3"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5534"
x="280.5639"
y="255.66946">move 2</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
docs/img/lookahead.svg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

207
docs/img/ooze.svg Normal file
View File

@@ -0,0 +1,207 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="98.140816mm"
height="63.537022mm"
viewBox="0 0 347.74305 225.13119"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="ooze.svg"
inkscape:export-filename="/home/kevin/src/reprap/firmware/klipper/docs/img/ooze.svg.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.94"
inkscape:cx="199.68782"
inkscape:cy="58.510649"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1091"
inkscape:window-height="588"
inkscape:window-x="266"
inkscape:window-y="106"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showborder="false"
inkscape:snap-global="false"
showguides="false">
<inkscape:grid
type="xygrid"
id="grid3436"
originx="-1.5695746e-05"
originy="109.79552" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-135.22431,-249.96955)">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 1.06383,102.12765 327.12765,-0.53192 -7.97871,5.85107"
id="path3347"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.50000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-346.84067"
y="139.75046"
id="text3353"
sodipodi:linespacing="125%"
transform="matrix(-0.01601372,-0.99987177,0.99987177,-0.01601372,0,0)"><tspan
sodipodi:role="line"
id="tspan12733"
x="-346.84067"
y="139.75046">head velocity</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 -5.31915,8.51063"
id="path3359"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.00000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 179.63013,351.45141 16.05677,-60.94328 120.91957,-1.06383 16.53759,62.00711"
id="path3361"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.78742969px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 332.99641,351.24986 16.72764,-63.00287 133.24331,0"
id="path3361-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.25000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="200.11789"
y="284.45413"
id="text12656"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan12658"
x="200.11789"
y="284.45413">extrude move</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.25000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="356.50089"
y="283.39032"
id="text12660"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan12662"
x="356.50089"
y="283.39032">non-extrude move</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 152.72419,471.73218 1.06383,102.12766 327.12768,-0.53192 -7.97872,5.85107"
id="path3347-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.5px;line-height:100%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="436.76678"
y="586.62585"
id="text3349-3"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan3351-4"
x="436.76678"
y="586.62585">time</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.50000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-551.11292"
y="125.37186"
id="text3353-0"
sodipodi:linespacing="125%"
transform="matrix(-0.01601372,-0.99987177,0.99987177,-0.01601372,0,0)"><tspan
sodipodi:role="line"
id="tspan4197"
x="-551.11292"
y="125.37186">actual</tspan><tspan
sodipodi:role="line"
id="tspan4199"
x="-551.11292"
y="140.99686">filament</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 152.72419,471.73218 -5.31915,8.51063"
id="path3359-9"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.00000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 182.35432,572.94905 c 17.46262,-43.80215 52.67413,-56.54375 92.65253,-60.94329 l 48.57915,-1.06383 c 24.916,55.4715 110.00504,59.23318 151.64398,62.00712"
id="path3361-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150.87843,360.66993 1.06383,102.12766 327.12768,-0.53192 -7.97872,5.85107"
id="path3347-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.50000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-444.27307"
y="124.17301"
id="text3353-6"
sodipodi:linespacing="125%"
transform="matrix(-0.01601372,-0.99987177,0.99987177,-0.01601372,0,0)"><tspan
sodipodi:role="line"
id="tspan4193"
x="-444.27307"
y="124.17301">desired</tspan><tspan
sodipodi:role="line"
id="tspan4195"
x="-444.27307"
y="139.79802">filament</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150.87843,360.66993 -5.31915,8.51063"
id="path3359-8"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.00000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 180.50856,461.8868 16.05678,-60.94329 120.91958,-1.06383 16.53759,62.00712"
id="path3361-4"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.8 KiB

BIN
docs/img/ooze.svg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1,207 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="102.61139mm"
height="99.266594mm"
viewBox="0 0 363.58366 351.73204"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="pressure-advance.svg"
inkscape:export-filename="/home/kevin/src/reprap/firmware/klipper/docs/img/pressure-advance.svg.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.97968464"
inkscape:cx="147.06528"
inkscape:cy="169.55487"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1091"
inkscape:window-height="588"
inkscape:window-x="419"
inkscape:window-y="273"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showborder="false"
inkscape:snap-global="false"
showguides="false">
<inkscape:grid
type="xygrid"
id="grid3436"
originx="17.089787"
originy="126.61899" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-118.13451,-140.19216)">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150.47693,249.82417 0.58688,123.9666 m 0,-21.42857 327.12765,-0.53192 -7.97871,5.85107"
id="path3347"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.50000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-334.86746"
y="122.91875"
id="text3353"
sodipodi:linespacing="125%"
transform="matrix(-0.01601372,-0.99987177,0.99987177,-0.01601372,0,0)"><tspan
sodipodi:role="line"
id="tspan12816"
x="-334.86746"
y="122.91875">extruder</tspan><tspan
sodipodi:role="line"
id="tspan12818"
x="-334.86746"
y="138.54375">velocity</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 -5.31915,8.51063"
id="path3359"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.00000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 316.60647,311.78473 16.53759,62.00711 m -154.57776,-52.12767 16.05677,-60.94328 1.06383,29.78724 m 0,0 120.91957,-1.06383 0,22.34043"
id="path3361"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 148.75077,140.45716 1.06383,102.12766 327.12769,-0.53192 -7.97872,5.85107"
id="path3347-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.50000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-237.05733"
y="140.25932"
id="text3353-2"
sodipodi:linespacing="125%"
transform="matrix(-0.01601372,-0.99987177,0.99987177,-0.01601372,0,0)"><tspan
sodipodi:role="line"
id="tspan12733-6"
x="-237.05733"
y="140.25932">head velocity</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 148.75077,140.45716 -5.31915,8.51063"
id="path3359-7"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.00000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 178.3809,241.67403 16.05679,-60.94329 120.91958,-1.06383 16.53759,62.00712"
id="path3361-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.78742969px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 331.74721,241.47248 16.72764,-63.00288 133.24332,0"
id="path3361-7-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.25000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="198.86868"
y="174.67674"
id="text12656-9"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan12658-8"
x="198.86868"
y="174.67674">extrude move</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.25000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="355.25165"
y="173.61293"
id="text12660-7"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan12662-2"
x="355.25165"
y="173.61293">non-extrude move</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 151.94226,384.0742 1.06383,102.12766 327.12769,-0.53192 -7.97872,5.85107"
id="path3347-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.50000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-467.65732"
y="122.73453"
id="text3353-1"
sodipodi:linespacing="125%"
transform="matrix(-0.01601372,-0.99987177,0.99987177,-0.01601372,0,0)"><tspan
sodipodi:role="line"
id="tspan12868"
x="-467.65732"
y="122.73453">extruder</tspan><tspan
sodipodi:role="line"
id="tspan12870"
x="-467.65732"
y="138.35953">pressure</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 151.94226,384.0742 -5.31915,8.51063"
id="path3359-5"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.00000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 181.57239,485.29107 16.05679,-60.94329 120.91958,-1.06383 16.53759,62.00712"
id="path3361-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.5px;line-height:100%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="438.03586"
y="499.53384"
id="text3349"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan3351"
x="438.03586"
y="499.53384">time</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -0,0 +1,180 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="102.04809mm"
height="61.494076mm"
viewBox="0 0 361.58771 217.8924"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="pressure-cornering.svg"
inkscape:export-filename="/home/kevin/src/reprap/firmware/klipper/docs/img/pressure-cornering.svg.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.98"
inkscape:cx="110.74341"
inkscape:cy="35.715236"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1091"
inkscape:window-height="588"
inkscape:window-x="656"
inkscape:window-y="0"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showborder="false"
inkscape:snap-global="false"
showguides="false">
<inkscape:grid
type="xygrid"
id="grid3436"
originx="17.089805"
originy="-7.2206491" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-118.13449,-140.19216)">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 1.06383,102.12765 327.12765,-0.53192 -7.97871,5.85107"
id="path3347"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.50000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-334.86746"
y="122.91875"
id="text3353"
sodipodi:linespacing="125%"
transform="matrix(-0.01601372,-0.99987177,0.99987177,-0.01601372,0,0)"><tspan
sodipodi:role="line"
id="tspan12816"
x="-334.86746"
y="122.91875">extruder</tspan><tspan
sodipodi:role="line"
id="tspan12818"
x="-334.86746"
y="138.54375">velocity</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 -5.31915,8.51063"
id="path3359"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.00000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 178.5663,321.66417 16.05677,-60.94328 1.06383,29.78724 m 0,0 117.21969,-0.77616 5.99519,7.3871 5.9952,-6.89861 131.50541,-0.77616"
id="path3361"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 148.75077,140.45716 1.06383,102.12766 327.12769,-0.53192 -7.97872,5.85107"
id="path3347-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.50000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-237.05733"
y="140.25932"
id="text3353-2"
sodipodi:linespacing="125%"
transform="matrix(-0.01601372,-0.99987177,0.99987177,-0.01601372,0,0)"><tspan
sodipodi:role="line"
id="tspan12733-6"
x="-237.05733"
y="140.25932">head velocity</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 148.75077,140.45716 -5.31915,8.51063"
id="path3359-7"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.00000024;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 178.3809,241.67403 16.05679,-60.94329 120.91958,-1.06383 4.29269,10.98671"
id="path3361-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 319.50231,193.5133 4.48274,-15.0437 133.24332,0"
id="path3361-7-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.25px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="198.86868"
y="174.67674"
id="text12656-9"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan12891"
x="198.86868"
y="174.67674">first extrude</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:11.25px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="355.25165"
y="173.61293"
id="text12660-7"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan12893"
x="355.25165"
y="173.61293">second extrude</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:4, 2, 1, 2;stroke-dashoffset:0;stroke-opacity:1"
d="m 314.05288,288.86296 0,17.34694 5.10204,17.34694 -1.02041,-48.97959 7.14286,-17.34694 0,31.63265"
id="path12895"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.5px;line-height:100%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="435.80841"
y="366.8262"
id="text3349"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan3351"
x="435.80841"
y="366.8262">time</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

132
docs/img/smoothed.svg Normal file
View File

@@ -0,0 +1,132 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="97.22496mm"
height="32.550285mm"
viewBox="0 0 344.49789 115.33566"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="smoothed.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.75"
inkscape:cx="167.32577"
inkscape:cy="45.708959"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="840"
inkscape:window-height="628"
inkscape:window-x="162"
inkscape:window-y="50"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showborder="false"
inkscape:snap-global="false"
showguides="false">
<inkscape:grid
type="xygrid"
id="grid3436" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-135.22429,-249.96955)">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 1.06383,102.12765 327.12765,-0.53192 -7.97871,5.85107"
id="path3347"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.5px;line-height:100%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="434.04257"
y="365.1282"
id="text3349"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan3351"
x="434.04257"
y="365.1282">time</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.5px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-313.86618"
y="140.27856"
id="text3353"
sodipodi:linespacing="125%"
transform="matrix(-0.01601372,-0.99987177,0.99987177,-0.01601372,0,0)"><tspan
sodipodi:role="line"
id="tspan3355"
x="-313.86618"
y="140.27856">velocity</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 -5.31915,8.51063"
id="path3359"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 165.50998,351.59092 15.42857,-35.42857 35.71428,0 11.71429,36.57143"
id="path3362"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.07142997px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 227.83578,352.85633 15.76217,-47.37239 22.00135,0 5.58242,17.6933"
id="path3362-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.21482575px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 271.35434,323.73296 11.15454,-30.54076 19.27119,-0.11152 8.73883,29.51288"
id="path3362-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.01949775px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 311.26144,322.49329 11.63197,-21.06975 15.33656,0 13.51652,50.22357"
id="path3362-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:2.00000012, 1.00000006, 0.50000003, 1.00000006;stroke-dashoffset:0;stroke-opacity:1"
d="m 165.50999,351.59092 33.14285,-34.28571 29.14286,34.28571"
id="path3426"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
docs/img/smoothed.svg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

102
docs/img/trapezoid.svg Normal file
View File

@@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="97.22496mm"
height="32.550285mm"
viewBox="0 0 344.49789 115.33566"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="trapezoid.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.94"
inkscape:cx="294.7319"
inkscape:cy="45.708959"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1091"
inkscape:window-height="588"
inkscape:window-x="113"
inkscape:window-y="31"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showborder="false" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-135.22429,-249.96955)">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 1.06383,102.12765 327.12765,-0.53192 -7.97871,5.85107"
id="path3347"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.5px;line-height:100%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="434.04257"
y="365.1282"
id="text3349"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan3351"
x="434.04257"
y="365.1282">time</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.5px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-313.86618"
y="140.27856"
id="text3353"
sodipodi:linespacing="125%"
transform="matrix(-0.01601372,-0.99987177,0.99987177,-0.01601372,0,0)"><tspan
sodipodi:role="line"
id="tspan3355"
x="-313.86618"
y="140.27856">velocity</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 -5.31915,8.51063"
id="path3359"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 179.78723,351.29837 41.48937,-60.63829 158.51063,0 37.23405,60.63829"
id="path3361"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
docs/img/trapezoid.svg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

182
docs/img/trapezoids.svg Normal file
View File

@@ -0,0 +1,182 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="97.22496mm"
height="32.550285mm"
viewBox="0 0 344.49789 115.33566"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="trapezoids.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.67"
inkscape:cx="164.48301"
inkscape:cy="76.011989"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1091"
inkscape:window-height="588"
inkscape:window-x="113"
inkscape:window-y="31"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showborder="false"
inkscape:snap-global="false"
showguides="false">
<inkscape:grid
type="xygrid"
id="grid3436" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-135.22429,-249.96955)">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 1.06383,102.12765 327.12765,-0.53192 -7.97871,5.85107"
id="path3347"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.5px;line-height:100%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="434.04257"
y="365.1282"
id="text3349"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan3351"
x="434.04257"
y="365.1282">time</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.5px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-313.86618"
y="140.27856"
id="text3353"
sodipodi:linespacing="125%"
transform="matrix(-0.01601372,-0.99987177,0.99987177,-0.01601372,0,0)"><tspan
sodipodi:role="line"
id="tspan3355"
x="-313.86618"
y="140.27856">velocity</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 -5.31915,8.51063"
id="path3359"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.62366331px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 179.63013,351.45141 16.05677,-60.94328 61.3451,0 6.96312,32.21987"
id="path3361"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.7558428px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 263.83557,321.45597 11.41184,-61.95224 59.85662,0 9.80496,29.88826"
id="path3361-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.7558428px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 344.93248,289.80297 59.85663,0 15.12411,61.95225"
id="path3361-7-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 263.86975,321.69491 0.37453,30.52957"
id="path3412"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 345.25947,289.31929 0.14909,62.46104"
id="path3414"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 222.45831,289.77329 -0.0598,62.07666"
id="path3416"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:20.00000119px;line-height:125%;font-family:'DejaVu Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;-inkscape-font-specification:'DejaVu Sans, Normal';font-stretch:normal;font-variant:normal;text-anchor:start;text-align:start;writing-mode:lr;"
x="193.73491"
y="338.70944"
id="text3418"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3420"
x="193.73491"
y="338.70944">1</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:20.00000191px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="236.28812"
y="338.70947"
id="text3422"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3434"
x="236.28812"
y="338.70947">2</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:20.00000191px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="294.79874"
y="335.51794"
id="text3426"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3428"
x="294.79874"
y="335.51794">3</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:20.00000119px;line-height:125%;font-family:'DejaVu Sans';letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;-inkscape-font-specification:'DejaVu Sans, Normal';font-stretch:normal;font-variant:normal;text-anchor:start;text-align:start;writing-mode:lr;"
x="367.13916"
y="337.6456"
id="text3430"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan3432"
x="367.13916"
y="337.6456">4</tspan></text>
</g>
</svg>

After

Width:  |  Height:  |  Size: 8.3 KiB

BIN
docs/img/trapezoids.svg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

241
docs/img/virtual-tower.svg Normal file
View File

@@ -0,0 +1,241 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64.619751mm"
height="27.45583mm"
viewBox="0 0 228.96762 97.284438"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="virtual-tower.svg">
<defs
id="defs4">
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker6618"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Mend">
<path
transform="matrix(-0.4,0,0,-0.4,-4,0)"
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
id="path6620"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="marker6500"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path6502"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.4,0,0,-0.4,-4,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend"
style="overflow:visible"
inkscape:isstock="true"
inkscape:collect="always">
<path
id="path5747"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.4,0,0,-0.4,-4,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mstart"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path5744"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
transform="matrix(0.4,0,0,0.4,4,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend-1"
style="overflow:visible"
inkscape:isstock="true"
inkscape:collect="always">
<path
inkscape:connector-curvature="0"
id="path4329-1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker6082"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Mend"
inkscape:collect="always">
<path
inkscape:connector-curvature="0"
transform="matrix(-0.4,0,0,-0.4,-4,0)"
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
id="path6084" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.75"
inkscape:cx="169.7719"
inkscape:cy="-4.0565054"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="922"
inkscape:window-height="628"
inkscape:window-x="162"
inkscape:window-y="50"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showborder="false"
inkscape:snap-global="false"
showguides="false">
<inkscape:grid
type="xygrid"
id="grid3436"
originx="-14.085234"
originy="-95.286988" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-149.30952,-172.73378)">
<path
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
d="m 176.36712,256.16235 200.00001,-0.57143"
id="path5510"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-254.01012"
y="369.20834"
id="text6058"
sodipodi:linespacing="125%"
transform="matrix(-0.01833576,-0.99983189,0.99983189,-0.01833576,0,0)"
inkscape:transform-center-x="-8.0000002"
inkscape:transform-center-y="12.571429"><tspan
sodipodi:role="line"
id="tspan10365"
x="-254.01012"
y="369.20834">virtual tower</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="148.36713"
y="269.87662"
id="text6062"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan6064"
x="148.36713"
y="269.87662">line of movement</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="237.50998"
y="251.01949"
id="text6066"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan6068"
x="237.50998"
y="251.01949">move</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:7.00000048;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 358.08141,255.01949 0,-82.28571"
id="path10351"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 220.36713,255.01949 357.50998,173.30521"
id="path10373"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="200.36713"
y="187.59093"
id="text10375"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan10377"
x="200.36713"
y="187.59093">virtual arm</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker6082)"
d="m 261.76375,182.85539 c 22.73118,-0.70136 26.45506,3.7437 40.00001,18.28573"
id="path6074"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend-1)"
d="m 219.61431,255.37268 70.93001,0.37408"
id="path3514-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

241
docs/img/xy+z-tower.svg Normal file
View File

@@ -0,0 +1,241 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64.619751mm"
height="27.45583mm"
viewBox="0 0 228.96762 97.284438"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="xy+z-tower.svg">
<defs
id="defs4">
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker6618"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Mend">
<path
transform="matrix(-0.4,0,0,-0.4,-4,0)"
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
id="path6620"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="marker6500"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path6502"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.4,0,0,-0.4,-4,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend"
style="overflow:visible"
inkscape:isstock="true"
inkscape:collect="always">
<path
id="path5747"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.4,0,0,-0.4,-4,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mstart"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path5744"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
transform="matrix(0.4,0,0,0.4,4,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Mend"
orient="auto"
refY="0"
refX="0"
id="Arrow1Mend-1"
style="overflow:visible"
inkscape:isstock="true"
inkscape:collect="always">
<path
inkscape:connector-curvature="0"
id="path4329-1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker6082"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Mend"
inkscape:collect="always">
<path
inkscape:connector-curvature="0"
transform="matrix(-0.4,0,0,-0.4,-4,0)"
style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1pt;stroke-opacity:1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
id="path6084" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.75"
inkscape:cx="169.7719"
inkscape:cy="-4.0565054"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="922"
inkscape:window-height="628"
inkscape:window-x="162"
inkscape:window-y="50"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showborder="false"
inkscape:snap-global="false"
showguides="false">
<inkscape:grid
type="xygrid"
id="grid3436"
originx="-14.085234"
originy="-95.286988" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-149.30952,-172.73378)">
<path
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow1Mstart);marker-end:url(#Arrow1Mend)"
d="m 176.36712,256.16235 200.00001,-0.57143"
id="path5510"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-119.27526"
y="434.37329"
id="text6058"
sodipodi:linespacing="125%"
transform="matrix(0.32454206,-0.94587127,0.94587127,0.32454206,0,0)"
inkscape:transform-center-x="-3.9400734"
inkscape:transform-center-y="14.789029"><tspan
sodipodi:role="line"
id="tspan10365"
x="-119.27526"
y="434.37329">virtual tower</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="148.36713"
y="269.87662"
id="text6062"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan6064"
x="148.36713"
y="269.87662">line of movement</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="237.50998"
y="251.01949"
id="text6066"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan6068"
x="237.50998"
y="251.01949">move</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:7.00000048;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 354.70239,255.76769 28.12779,-77.32895"
id="path10351"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="M 220.36713,255.01949 380.93855,178.44807"
id="path10373"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:10.00000095px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="200.36713"
y="187.59093"
id="text10375"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan10377"
x="200.36713"
y="187.59093">virtual arm</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#4b4b4b;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker6082)"
d="m 261.76375,182.85539 c 22.73118,-0.70136 26.45506,3.7437 40.00001,18.28573"
id="path6074"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:3;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Mend-1)"
d="m 219.61431,255.37268 70.93001,0.37408"
id="path3514-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 9.5 KiB

BIN
docs/img/xy+z-tower.svg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

126
docs/img/zigzag.svg Normal file
View File

@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="97.22496mm"
height="32.550285mm"
viewBox="0 0 344.49789 115.33566"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="zigzag.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.75"
inkscape:cx="167.32577"
inkscape:cy="45.708959"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="840"
inkscape:window-height="628"
inkscape:window-x="160"
inkscape:window-y="35"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showborder="false"
inkscape:snap-global="false"
showguides="false">
<inkscape:grid
type="xygrid"
id="grid3436" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-135.22429,-249.96955)">
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 1.06383,102.12765 327.12765,-0.53192 -7.97871,5.85107"
id="path3347"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.5px;line-height:100%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="434.04257"
y="365.1282"
id="text3349"
sodipodi:linespacing="100%"><tspan
sodipodi:role="line"
id="tspan3351"
x="434.04257"
y="365.1282">time</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:12.5px;line-height:125%;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans, Normal';text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-313.86618"
y="140.27856"
id="text3353"
sodipodi:linespacing="125%"
transform="matrix(-0.01601372,-0.99987177,0.99987177,-0.01601372,0,0)"><tspan
sodipodi:role="line"
id="tspan3355"
x="-313.86618"
y="140.27856">velocity</tspan></text>
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 150,250.23455 -5.31915,8.51063"
id="path3359"
inkscape:connector-curvature="0" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 165.50998,351.59092 24.57143,-73.14286 23.42857,73.14286"
id="path3362"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 214.08032,352.31321 24.57144,-73.14287 13.14286,43.42858"
id="path3362-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.09757805px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 252.42963,323.78006 17.64919,-60.34771 14.22362,59.20485"
id="path3362-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccc" />
<path
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 284.36604,322.59892 14.85715,-44.00001 3.71429,0 16.85715,73.14287"
id="path3362-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.1 KiB

BIN
docs/img/zigzag.svg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

14
docs/prints/square.scad Normal file
View File

@@ -0,0 +1,14 @@
// Test square
//
// Generate STL using OpenSCAD:
// openscad square.scad -o square.stl
square_width = 5;
square_size = 60;
square_height = 5;
difference() {
cube([square_size, square_size, square_height]);
translate([square_width, square_width, -1])
cube([square_size-2*square_width, square_size-2*square_width, square_height+2]);
}

226
docs/prints/square.stl Normal file
View File

@@ -0,0 +1,226 @@
solid OpenSCAD_Model
facet normal -1 0 0
outer loop
vertex 0 0 0
vertex 0 60 5
vertex 0 60 0
endloop
endfacet
facet normal -1 -0 0
outer loop
vertex 0 60 5
vertex 0 0 0
vertex 0 0 5
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 60 60 5
vertex 55 55 5
vertex 60 0 5
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 60 60 5
vertex 5 55 5
vertex 55 55 5
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 5 55 5
vertex 0 60 5
vertex 5 5 5
endloop
endfacet
facet normal -0 0 1
outer loop
vertex 0 60 5
vertex 5 55 5
vertex 60 60 5
endloop
endfacet
facet normal -0 0 1
outer loop
vertex 55 5 5
vertex 60 0 5
vertex 55 55 5
endloop
endfacet
facet normal -0 0 1
outer loop
vertex 5 5 5
vertex 60 0 5
vertex 55 5 5
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 5 5 5
vertex 0 0 5
vertex 60 0 5
endloop
endfacet
facet normal 0 0 1
outer loop
vertex 0 0 5
vertex 5 5 5
vertex 0 60 5
endloop
endfacet
facet normal 1 -0 0
outer loop
vertex 60 0 5
vertex 60 60 0
vertex 60 60 5
endloop
endfacet
facet normal 1 0 0
outer loop
vertex 60 60 0
vertex 60 0 5
vertex 60 0 0
endloop
endfacet
facet normal 0 1 -0
outer loop
vertex 60 60 0
vertex 0 60 5
vertex 60 60 5
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 0 60 5
vertex 60 60 0
vertex 0 60 0
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 60 0 0
vertex 55 5 0
vertex 60 60 0
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 60 0 0
vertex 5 5 0
vertex 55 5 0
endloop
endfacet
facet normal -0 0 -1
outer loop
vertex 5 5 0
vertex 0 0 0
vertex 5 55 0
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 0 0 0
vertex 5 5 0
vertex 60 0 0
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 55 55 0
vertex 60 60 0
vertex 55 5 0
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 5 55 0
vertex 60 60 0
vertex 55 55 0
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 5 55 0
vertex 0 60 0
vertex 60 60 0
endloop
endfacet
facet normal 0 0 -1
outer loop
vertex 0 60 0
vertex 5 55 0
vertex 0 0 0
endloop
endfacet
facet normal 0 -1 0
outer loop
vertex 0 0 0
vertex 60 0 5
vertex 0 0 5
endloop
endfacet
facet normal 0 -1 -0
outer loop
vertex 60 0 5
vertex 0 0 0
vertex 60 0 0
endloop
endfacet
facet normal 1 -0 0
outer loop
vertex 5 5 5
vertex 5 55 0
vertex 5 55 5
endloop
endfacet
facet normal 1 0 0
outer loop
vertex 5 55 0
vertex 5 5 5
vertex 5 5 0
endloop
endfacet
facet normal -1 0 0
outer loop
vertex 55 5 0
vertex 55 55 5
vertex 55 55 0
endloop
endfacet
facet normal -1 -0 0
outer loop
vertex 55 55 5
vertex 55 5 0
vertex 55 5 5
endloop
endfacet
facet normal 0 1 -0
outer loop
vertex 55 5 0
vertex 5 5 5
vertex 55 5 5
endloop
endfacet
facet normal 0 1 0
outer loop
vertex 5 5 5
vertex 55 5 0
vertex 5 5 0
endloop
endfacet
facet normal 0 -1 0
outer loop
vertex 5 55 0
vertex 55 55 5
vertex 5 55 5
endloop
endfacet
facet normal 0 -1 -0
outer loop
vertex 55 55 5
vertex 5 55 0
vertex 55 55 0
endloop
endfacet
endsolid OpenSCAD_Model

132
klippy/cartesian.py Normal file
View File

@@ -0,0 +1,132 @@
# Code for handling the kinematics of cartesian robots
#
# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import logging
import stepper, homing
StepList = (0, 1, 2)
class CartKinematics:
def __init__(self, printer, config):
self.steppers = [stepper.PrinterStepper(
printer, config.getsection('stepper_' + n), n)
for n in ['x', 'y', 'z']]
self.max_z_velocity = config.getfloat(
'max_z_velocity', 9999999.9, above=0.)
self.max_z_accel = config.getfloat(
'max_z_accel', 9999999.9, above=0.)
self.need_motor_enable = True
self.limits = [(1.0, -1.0)] * 3
def set_max_jerk(self, max_xy_halt_velocity, max_velocity, max_accel):
self.steppers[0].set_max_jerk(max_xy_halt_velocity, max_accel)
self.steppers[1].set_max_jerk(max_xy_halt_velocity, max_accel)
self.steppers[2].set_max_jerk(0., self.max_z_accel)
def set_position(self, newpos):
for i in StepList:
self.steppers[i].mcu_stepper.set_position(newpos[i])
def home(self, homing_state):
# Each axis is homed independently and in order
for axis in homing_state.get_axes():
s = self.steppers[axis]
self.limits[axis] = (s.position_min, s.position_max)
# Determine moves
if s.homing_positive_dir:
pos = s.position_endstop - 1.5*(
s.position_endstop - s.position_min)
rpos = s.position_endstop - s.homing_retract_dist
r2pos = rpos - s.homing_retract_dist
else:
pos = s.position_endstop + 1.5*(
s.position_max - s.position_endstop)
rpos = s.position_endstop + s.homing_retract_dist
r2pos = rpos + s.homing_retract_dist
# Initial homing
homepos = [None, None, None, None]
homepos[axis] = s.position_endstop
coord = [None, None, None, None]
coord[axis] = pos
homing_state.home(list(coord), homepos, [s], s.homing_speed)
# Retract
coord[axis] = rpos
homing_state.retract(list(coord), s.homing_speed)
# Home again
coord[axis] = r2pos
homing_state.home(
list(coord), homepos, [s], s.homing_speed/2.0, second_home=True)
# Set final homed position
coord[axis] = s.position_endstop + s.get_homed_offset()
homing_state.set_homed_position(coord)
def motor_off(self, move_time):
self.limits = [(1.0, -1.0)] * 3
for stepper in self.steppers:
stepper.motor_enable(move_time, 0)
self.need_motor_enable = True
def _check_motor_enable(self, move_time, move):
need_motor_enable = False
for i in StepList:
if move.axes_d[i]:
self.steppers[i].motor_enable(move_time, 1)
need_motor_enable |= self.steppers[i].need_motor_enable
self.need_motor_enable = need_motor_enable
def query_endstops(self, print_time):
endstops = [(s, s.query_endstop(print_time)) for s in self.steppers]
return [(s.name, es.query_endstop_wait()) for s, es in endstops]
def _check_endstops(self, move):
end_pos = move.end_pos
for i in StepList:
if (move.axes_d[i]
and (end_pos[i] < self.limits[i][0]
or end_pos[i] > self.limits[i][1])):
if self.limits[i][0] > self.limits[i][1]:
raise homing.EndstopMoveError(
end_pos, "Must home axis first")
raise homing.EndstopMoveError(end_pos)
def check_move(self, move):
limits = self.limits
xpos, ypos = move.end_pos[:2]
if (xpos < limits[0][0] or xpos > limits[0][1]
or ypos < limits[1][0] or ypos > limits[1][1]):
self._check_endstops(move)
if not move.axes_d[2]:
# Normal XY move - use defaults
return
# Move with Z - update velocity and accel for slower Z axis
self._check_endstops(move)
z_ratio = move.move_d / abs(move.axes_d[2])
move.limit_speed(
self.max_z_velocity * z_ratio, self.max_z_accel * z_ratio)
def move(self, move_time, move):
if self.need_motor_enable:
self._check_motor_enable(move_time, move)
for i in StepList:
axis_d = move.axes_d[i]
if not axis_d:
continue
mcu_stepper = self.steppers[i].mcu_stepper
mcu_time = mcu_stepper.print_to_mcu_time(move_time)
start_pos = move.start_pos[i]
axis_r = abs(axis_d) / move.move_d
accel = move.accel * axis_r
cruise_v = move.cruise_v * axis_r
# Acceleration steps
if move.accel_r:
accel_d = move.accel_r * axis_d
mcu_stepper.step_const(
mcu_time, start_pos, accel_d, move.start_v * axis_r, accel)
start_pos += accel_d
mcu_time += move.accel_t
# Cruising steps
if move.cruise_r:
cruise_d = move.cruise_r * axis_d
mcu_stepper.step_const(
mcu_time, start_pos, cruise_d, cruise_v, 0.)
start_pos += cruise_d
mcu_time += move.cruise_t
# Deceleration steps
if move.decel_r:
decel_d = move.decel_r * axis_d
mcu_stepper.step_const(
mcu_time, start_pos, decel_d, cruise_v, -accel)

135
klippy/chelper.py Normal file
View File

@@ -0,0 +1,135 @@
# Wrapper around C helper code
#
# Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import os, logging
import cffi
######################################################################
# c_helper.so compiling
######################################################################
COMPILE_CMD = "gcc -Wall -g -O2 -shared -fPIC -o %s %s"
SOURCE_FILES = ['stepcompress.c', 'serialqueue.c', 'pyhelper.c']
DEST_LIB = "c_helper.so"
OTHER_FILES = ['list.h', 'serialqueue.h', 'pyhelper.h']
defs_stepcompress = """
struct stepcompress *stepcompress_alloc(uint32_t max_error
, uint32_t queue_step_msgid, uint32_t set_next_step_dir_msgid
, uint32_t invert_sdir, uint32_t oid);
void stepcompress_free(struct stepcompress *sc);
int stepcompress_reset(struct stepcompress *sc, uint64_t last_step_clock);
int stepcompress_set_homing(struct stepcompress *sc, uint64_t homing_clock);
int stepcompress_queue_msg(struct stepcompress *sc, uint32_t *data, int len);
int stepcompress_push(struct stepcompress *sc, double step_clock
, int32_t sdir);
int32_t stepcompress_push_const(struct stepcompress *sc, double clock_offset
, double step_offset, double steps, double start_sv, double accel);
int32_t stepcompress_push_delta(struct stepcompress *sc
, double clock_offset, double move_sd, double start_sv, double accel
, double height, double startxy_sd, double arm_d, double movez_r);
struct steppersync *steppersync_alloc(struct serialqueue *sq
, struct stepcompress **sc_list, int sc_num, int move_num);
void steppersync_free(struct steppersync *ss);
int steppersync_flush(struct steppersync *ss, uint64_t move_clock);
"""
defs_serialqueue = """
#define MESSAGE_MAX 64
struct pull_queue_message {
uint8_t msg[MESSAGE_MAX];
int len;
double sent_time, receive_time;
};
struct serialqueue *serialqueue_alloc(int serial_fd, int write_only);
void serialqueue_exit(struct serialqueue *sq);
void serialqueue_free(struct serialqueue *sq);
struct command_queue *serialqueue_alloc_commandqueue(void);
void serialqueue_free_commandqueue(struct command_queue *cq);
void serialqueue_send(struct serialqueue *sq, struct command_queue *cq
, uint8_t *msg, int len, uint64_t min_clock, uint64_t req_clock);
void serialqueue_encode_and_send(struct serialqueue *sq
, struct command_queue *cq, uint32_t *data, int len
, uint64_t min_clock, uint64_t req_clock);
void serialqueue_pull(struct serialqueue *sq, struct pull_queue_message *pqm);
void serialqueue_set_baud_adjust(struct serialqueue *sq, double baud_adjust);
void serialqueue_set_clock_est(struct serialqueue *sq, double est_clock
, double last_ack_time, uint64_t last_ack_clock);
void serialqueue_get_stats(struct serialqueue *sq, char *buf, int len);
int serialqueue_extract_old(struct serialqueue *sq, int sentq
, struct pull_queue_message *q, int max);
"""
defs_pyhelper = """
void set_python_logging_callback(void (*func)(const char *));
double get_monotonic(void);
"""
# Return the list of file modification times
def get_mtimes(srcdir, filelist):
out = []
for filename in filelist:
pathname = os.path.join(srcdir, filename)
try:
t = os.path.getmtime(pathname)
except os.error:
continue
out.append(t)
return out
# Check if the code needs to be compiled
def check_build_code(srcdir, target, sources, cmd, other_files=[]):
src_times = get_mtimes(srcdir, sources + other_files)
obj_times = get_mtimes(srcdir, [target])
if not obj_times or max(src_times) > min(obj_times):
logging.info("Building C code module %s" % (target,))
srcfiles = [os.path.join(srcdir, fname) for fname in sources]
destlib = os.path.join(srcdir, target)
os.system(cmd % (destlib, ' '.join(srcfiles)))
FFI_main = None
FFI_lib = None
pyhelper_logging_callback = None
# Return the Foreign Function Interface api to the caller
def get_ffi():
global FFI_main, FFI_lib, pyhelper_logging_callback
if FFI_lib is None:
srcdir = os.path.dirname(os.path.realpath(__file__))
check_build_code(srcdir, DEST_LIB, SOURCE_FILES, COMPILE_CMD
, OTHER_FILES)
FFI_main = cffi.FFI()
FFI_main.cdef(defs_stepcompress)
FFI_main.cdef(defs_serialqueue)
FFI_main.cdef(defs_pyhelper)
FFI_lib = FFI_main.dlopen(os.path.join(srcdir, DEST_LIB))
# Setup error logging
def logging_callback(msg):
logging.error(FFI_main.string(msg))
pyhelper_logging_callback = FFI_main.callback(
"void(const char *)", logging_callback)
FFI_lib.set_python_logging_callback(pyhelper_logging_callback)
return FFI_main, FFI_lib
######################################################################
# hub-ctrl hub power controller
######################################################################
HC_COMPILE_CMD = "gcc -Wall -g -O2 -o %s %s -lusb"
HC_SOURCE_FILES = ['hub-ctrl.c']
HC_SOURCE_DIR = '../lib/hub-ctrl'
HC_TARGET = "hub-ctrl"
HC_CMD = "sudo %s/hub-ctrl -h 0 -P 2 -p %d"
def run_hub_ctrl(enable_power):
srcdir = os.path.dirname(os.path.realpath(__file__))
hubdir = os.path.join(srcdir, HC_SOURCE_DIR)
check_build_code(hubdir, HC_TARGET, HC_SOURCE_FILES, HC_COMPILE_CMD)
os.system(HC_CMD % (hubdir, enable_power))

119
klippy/console.py Executable file
View File

@@ -0,0 +1,119 @@
#!/usr/bin/env python
# Script to implement a test console with firmware over serial port
#
# Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import sys, optparse, os, re, logging
import reactor, serialhdl, pins, util, msgproto
re_eval = re.compile(r'\{(?P<eval>[^}]*)\}')
class KeyboardReader:
def __init__(self, ser, reactor):
self.ser = ser
self.reactor = reactor
self.fd = sys.stdin.fileno()
util.set_nonblock(self.fd)
self.mcu_freq = 0
self.pins = None
self.data = ""
reactor.register_fd(self.fd, self.process_kbd)
self.connect_timer = reactor.register_timer(self.connect, reactor.NOW)
self.local_commands = { "PINS": self.set_pin_map, "SET": self.set_var }
self.eval_globals = {}
def connect(self, eventtime):
self.ser.connect()
self.ser.handle_default = self.handle_default
self.mcu_freq = self.ser.msgparser.get_constant_float('CLOCK_FREQ')
mcu = self.ser.msgparser.get_constant('MCU')
self.pins = pins.get_pin_map(mcu)
self.reactor.unregister_timer(self.connect_timer)
return self.reactor.NEVER
def output(self, msg):
sys.stdout.write("%s\n" % (msg,))
sys.stdout.flush()
def handle_default(self, params):
self.output(self.ser.msgparser.format_params(params))
def update_evals(self, eventtime):
self.eval_globals['freq'] = self.mcu_freq
self.eval_globals['clock'] = self.ser.get_clock(eventtime)
def set_pin_map(self, parts):
mcu = self.ser.msgparser.get_constant('MCU')
self.pins = pins.get_pin_map(mcu, parts[1])
def set_var(self, parts):
val = parts[2]
try:
val = float(val)
except ValueError:
pass
self.eval_globals[parts[1]] = val
def translate(self, line, eventtime):
evalparts = re_eval.split(line)
if len(evalparts) > 1:
self.update_evals(eventtime)
try:
for i in range(1, len(evalparts), 2):
e = eval(evalparts[i], self.eval_globals)
if type(e) == type(0.):
e = int(e)
evalparts[i] = str(e)
except:
self.output("Unable to evaluate: %s" % (line,))
return None
line = ''.join(evalparts)
self.output("Eval: %s" % (line,))
if self.pins is not None:
try:
line = pins.update_command(
line, self.mcu_freq, self.pins).strip()
except:
self.output("Unable to map pin: %s" % (line,))
return None
if line:
parts = line.split()
if parts[0] in self.local_commands:
self.local_commands[parts[0]](parts)
return None
try:
msg = self.ser.msgparser.create_command(line)
except msgproto.error, e:
self.output("Error: %s" % (str(e),))
return None
return msg
def process_kbd(self, eventtime):
self.data += os.read(self.fd, 4096)
kbdlines = self.data.split('\n')
for line in kbdlines[:-1]:
line = line.strip()
cpos = line.find('#')
if cpos >= 0:
line = line[:cpos]
if not line:
continue
msg = self.translate(line.strip(), eventtime)
if msg is None:
continue
self.ser.send(msg)
self.data = kbdlines[-1]
def main():
usage = "%prog [options] <serialdevice> <baud>"
opts = optparse.OptionParser(usage)
options, args = opts.parse_args()
serialport, baud = args
baud = int(baud)
logging.basicConfig(level=logging.DEBUG)
r = reactor.Reactor()
ser = serialhdl.SerialReader(r, serialport, baud)
kbd = KeyboardReader(ser, r)
try:
r.run()
except KeyboardInterrupt:
sys.stdout.write("\n")
if __name__ == '__main__':
main()

146
klippy/corexy.py Normal file
View File

@@ -0,0 +1,146 @@
# Code for handling the kinematics of corexy robots
#
# Copyright (C) 2017 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import logging
import stepper, homing
StepList = (0, 1, 2)
class CoreXYKinematics:
def __init__(self, printer, config):
self.steppers = [stepper.PrinterStepper(
printer, config.getsection('stepper_' + n), n)
for n in ['x', 'y', 'z']]
self.steppers[0].mcu_endstop.add_stepper(self.steppers[1].mcu_stepper)
self.steppers[1].mcu_endstop.add_stepper(self.steppers[0].mcu_stepper)
self.max_z_velocity = config.getfloat(
'max_z_velocity', 9999999.9, above=0.)
self.max_z_accel = config.getfloat(
'max_z_accel', 9999999.9, above=0.)
self.need_motor_enable = True
self.limits = [(1.0, -1.0)] * 3
def set_max_jerk(self, max_xy_halt_velocity, max_velocity, max_accel):
self.steppers[0].set_max_jerk(max_xy_halt_velocity, max_accel)
self.steppers[1].set_max_jerk(max_xy_halt_velocity, max_accel)
self.steppers[2].set_max_jerk(0., self.max_z_accel)
def set_position(self, newpos):
pos = (newpos[0] + newpos[1], newpos[0] - newpos[1], newpos[2])
for i in StepList:
self.steppers[i].mcu_stepper.set_position(pos[i])
def home(self, homing_state):
# Each axis is homed independently and in order
for axis in homing_state.get_axes():
s = self.steppers[axis]
self.limits[axis] = (s.position_min, s.position_max)
# Determine moves
if s.homing_positive_dir:
pos = s.position_endstop - 1.5*(
s.position_endstop - s.position_min)
rpos = s.position_endstop - s.homing_retract_dist
r2pos = rpos - s.homing_retract_dist
else:
pos = s.position_endstop + 1.5*(
s.position_max - s.position_endstop)
rpos = s.position_endstop + s.homing_retract_dist
r2pos = rpos + s.homing_retract_dist
# Initial homing
homepos = [None, None, None, None]
homepos[axis] = s.position_endstop
coord = [None, None, None, None]
coord[axis] = pos
homing_state.home(list(coord), homepos, [s], s.homing_speed)
# Retract
coord[axis] = rpos
homing_state.retract(list(coord), s.homing_speed)
# Home again
coord[axis] = r2pos
homing_state.home(
list(coord), homepos, [s], s.homing_speed/2.0, second_home=True)
if axis == 2:
# Support endstop phase detection on Z axis
coord[axis] = s.position_endstop + s.get_homed_offset()
homing_state.set_homed_position(coord)
def motor_off(self, move_time):
self.limits = [(1.0, -1.0)] * 3
for stepper in self.steppers:
stepper.motor_enable(move_time, 0)
self.need_motor_enable = True
def _check_motor_enable(self, move_time, move):
if move.axes_d[0] or move.axes_d[1]:
self.steppers[0].motor_enable(move_time, 1)
self.steppers[1].motor_enable(move_time, 1)
if move.axes_d[2]:
self.steppers[2].motor_enable(move_time, 1)
need_motor_enable = False
for i in StepList:
need_motor_enable |= self.steppers[i].need_motor_enable
self.need_motor_enable = need_motor_enable
def query_endstops(self, print_time):
endstops = [(s, s.query_endstop(print_time)) for s in self.steppers]
return [(s.name, es.query_endstop_wait()) for s, es in endstops]
def _check_endstops(self, move):
end_pos = move.end_pos
for i in StepList:
if (move.axes_d[i]
and (end_pos[i] < self.limits[i][0]
or end_pos[i] > self.limits[i][1])):
if self.limits[i][0] > self.limits[i][1]:
raise homing.EndstopMoveError(
end_pos, "Must home axis first")
raise homing.EndstopMoveError(end_pos)
def check_move(self, move):
limits = self.limits
xpos, ypos = move.end_pos[:2]
if (xpos < limits[0][0] or xpos > limits[0][1]
or ypos < limits[1][0] or ypos > limits[1][1]):
self._check_endstops(move)
if not move.axes_d[2]:
# Normal XY move - use defaults
return
# Move with Z - update velocity and accel for slower Z axis
self._check_endstops(move)
z_ratio = move.move_d / abs(move.axes_d[2])
move.limit_speed(
self.max_z_velocity * z_ratio, self.max_z_accel * z_ratio)
def move(self, move_time, move):
if self.need_motor_enable:
self._check_motor_enable(move_time, move)
sxp = move.start_pos[0]
syp = move.start_pos[1]
move_start_pos = (sxp + syp, sxp - syp, move.start_pos[2])
exp = move.end_pos[0]
eyp = move.end_pos[1]
axes_d = ((exp + eyp) - move_start_pos[0],
(exp - eyp) - move_start_pos[1], move.axes_d[2])
for i in StepList:
axis_d = axes_d[i]
if not axis_d:
continue
mcu_stepper = self.steppers[i].mcu_stepper
mcu_time = mcu_stepper.print_to_mcu_time(move_time)
start_pos = move_start_pos[i]
axis_r = abs(axis_d) / move.move_d
accel = move.accel * axis_r
cruise_v = move.cruise_v * axis_r
# Acceleration steps
if move.accel_r:
accel_d = move.accel_r * axis_d
mcu_stepper.step_const(
mcu_time, start_pos, accel_d, move.start_v * axis_r, accel)
start_pos += accel_d
mcu_time += move.accel_t
# Cruising steps
if move.cruise_r:
cruise_d = move.cruise_r * axis_d
mcu_stepper.step_const(
mcu_time, start_pos, cruise_d, cruise_v, 0.)
start_pos += cruise_d
mcu_time += move.cruise_t
# Deceleration steps
if move.decel_r:
decel_d = move.decel_r * axis_d
mcu_stepper.step_const(
mcu_time, start_pos, decel_d, cruise_v, -accel)

244
klippy/delta.py Normal file
View File

@@ -0,0 +1,244 @@
# Code for handling the kinematics of linear delta robots
#
# Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import math, logging
import stepper, homing
StepList = (0, 1, 2)
# Slow moves once the ratio of tower to XY movement exceeds SLOW_RATIO
SLOW_RATIO = 3.
class DeltaKinematics:
def __init__(self, printer, config):
self.config = config
self.steppers = [stepper.PrinterStepper(
printer, config.getsection('stepper_' + n), n)
for n in ['a', 'b', 'c']]
self.need_motor_enable = self.need_home = True
self.max_velocity = self.max_z_velocity = self.max_accel = 0.
radius = config.getfloat('delta_radius', above=0.)
arm_length = config.getfloat('delta_arm_length', above=radius)
self.arm_length2 = arm_length**2
self.limit_xy2 = -1.
tower_height_at_zeros = math.sqrt(self.arm_length2 - radius**2)
self.max_z = max([s.position_endstop for s in self.steppers])
self.limit_z = self.max_z - (arm_length - tower_height_at_zeros)
logging.info(
"Delta max build height %.2fmm (radius tapered above %.2fmm)" % (
self.max_z, self.limit_z))
sin = lambda angle: math.sin(math.radians(angle))
cos = lambda angle: math.cos(math.radians(angle))
self.towers = [
(cos(210.)*radius, sin(210.)*radius),
(cos(330.)*radius, sin(330.)*radius),
(cos(90.)*radius, sin(90.)*radius)]
# Find the point where an XY move could result in excessive
# tower movement
half_min_step_dist = min([s.step_dist for s in self.steppers]) * .5
def ratio_to_dist(ratio):
return (ratio * math.sqrt(self.arm_length2 / (ratio**2 + 1.)
- half_min_step_dist**2)
+ half_min_step_dist)
self.slow_xy2 = (ratio_to_dist(SLOW_RATIO) - radius)**2
self.very_slow_xy2 = (ratio_to_dist(2. * SLOW_RATIO) - radius)**2
self.max_xy2 = min(radius, arm_length - radius,
ratio_to_dist(4. * SLOW_RATIO) - radius)**2
logging.info(
"Delta max build radius %.2fmm (moves slowed past %.2fmm and %.2fmm)"
% (math.sqrt(self.max_xy2), math.sqrt(self.slow_xy2),
math.sqrt(self.very_slow_xy2)))
self.set_position([0., 0., 0.])
def set_max_jerk(self, max_xy_halt_velocity, max_velocity, max_accel):
self.max_velocity = max_velocity
max_z_velocity = self.config.getfloat(
'max_z_velocity', max_velocity, above=0.)
self.max_z_velocity = min(max_velocity, max_z_velocity)
self.max_accel = max_accel
for stepper in self.steppers:
stepper.set_max_jerk(max_xy_halt_velocity, max_accel)
def _cartesian_to_actuator(self, coord):
return [math.sqrt(self.arm_length2
- (self.towers[i][0] - coord[0])**2
- (self.towers[i][1] - coord[1])**2) + coord[2]
for i in StepList]
def _actuator_to_cartesian(self, pos):
# Based on code from Smoothieware
tower1 = list(self.towers[0]) + [pos[0]]
tower2 = list(self.towers[1]) + [pos[1]]
tower3 = list(self.towers[2]) + [pos[2]]
s12 = matrix_sub(tower1, tower2)
s23 = matrix_sub(tower2, tower3)
s13 = matrix_sub(tower1, tower3)
normal = matrix_cross(s12, s23)
magsq_s12 = matrix_magsq(s12)
magsq_s23 = matrix_magsq(s23)
magsq_s13 = matrix_magsq(s13)
inv_nmag_sq = 1.0 / matrix_magsq(normal)
q = 0.5 * inv_nmag_sq
a = q * magsq_s23 * matrix_dot(s12, s13)
b = -q * magsq_s13 * matrix_dot(s12, s23) # negate because we use s12 instead of s21
c = q * magsq_s12 * matrix_dot(s13, s23)
circumcenter = [tower1[0] * a + tower2[0] * b + tower3[0] * c,
tower1[1] * a + tower2[1] * b + tower3[1] * c,
tower1[2] * a + tower2[2] * b + tower3[2] * c]
r_sq = 0.5 * q * magsq_s12 * magsq_s23 * magsq_s13
dist = math.sqrt(inv_nmag_sq * (self.arm_length2 - r_sq))
return matrix_sub(circumcenter, matrix_mul(normal, dist))
def set_position(self, newpos):
pos = self._cartesian_to_actuator(newpos)
for i in StepList:
self.steppers[i].mcu_stepper.set_position(pos[i])
self.limit_xy2 = -1.
def home(self, homing_state):
# All axes are homed simultaneously
homing_state.set_axes([0, 1, 2])
s = self.steppers[0] # Assume homing speed same for all steppers
self.need_home = False
# Initial homing
homepos = [0., 0., self.max_z, None]
coord = list(homepos)
coord[2] = -1.5 * math.sqrt(self.arm_length2-self.max_xy2)
homing_state.home(list(coord), homepos, self.steppers, s.homing_speed)
# Retract
coord[2] = homepos[2] - s.homing_retract_dist
homing_state.retract(list(coord), s.homing_speed)
# Home again
coord[2] -= s.homing_retract_dist
homing_state.home(list(coord), homepos, self.steppers
, s.homing_speed/2.0, second_home=True)
# Set final homed position
coord = [s.mcu_stepper.get_commanded_position() + s.get_homed_offset()
for s in self.steppers]
homing_state.set_homed_position(self._actuator_to_cartesian(coord))
def motor_off(self, move_time):
self.limit_xy2 = -1.
for stepper in self.steppers:
stepper.motor_enable(move_time, 0)
self.need_motor_enable = self.need_home = True
def _check_motor_enable(self, move_time):
for i in StepList:
self.steppers[i].motor_enable(move_time, 1)
self.need_motor_enable = False
def query_endstops(self, print_time):
endstops = [(s, s.query_endstop(print_time)) for s in self.steppers]
return [(s.name, es.query_endstop_wait()) for s, es in endstops]
def check_move(self, move):
end_pos = move.end_pos
xy2 = end_pos[0]**2 + end_pos[1]**2
if xy2 <= self.limit_xy2 and not move.axes_d[2]:
# Normal XY move
return
if self.need_home:
raise homing.EndstopMoveError(end_pos, "Must home first")
limit_xy2 = self.max_xy2
if end_pos[2] > self.limit_z:
limit_xy2 = min(limit_xy2, (self.max_z - end_pos[2])**2)
if xy2 > limit_xy2 or end_pos[2] < 0. or end_pos[2] > self.max_z:
raise homing.EndstopMoveError(end_pos)
if move.axes_d[2]:
move.limit_speed(self.max_z_velocity, move.accel)
limit_xy2 = -1.
# Limit the speed/accel of this move if is is at the extreme
# end of the build envelope
extreme_xy2 = max(xy2, move.start_pos[0]**2 + move.start_pos[1]**2)
if extreme_xy2 > self.slow_xy2:
r = 0.5
if extreme_xy2 > self.very_slow_xy2:
r = 0.25
max_velocity = self.max_velocity
if move.axes_d[2]:
max_velocity = self.max_z_velocity
move.limit_speed(max_velocity * r, self.max_accel * r)
limit_xy2 = -1.
self.limit_xy2 = min(limit_xy2, self.slow_xy2)
def move(self, move_time, move):
if self.need_motor_enable:
self._check_motor_enable(move_time)
axes_d = move.axes_d
move_d = move.move_d
movexy_r = 1.
movez_r = 0.
inv_movexy_d = 1. / move_d
if not axes_d[0] and not axes_d[1]:
# Z only move
movez_r = axes_d[2] * inv_movexy_d
movexy_r = inv_movexy_d = 0.
elif axes_d[2]:
# XY+Z move
movexy_d = math.sqrt(axes_d[0]**2 + axes_d[1]**2)
movexy_r = movexy_d * inv_movexy_d
movez_r = axes_d[2] * inv_movexy_d
inv_movexy_d = 1. / movexy_d
origx, origy, origz = move.start_pos[:3]
accel = move.accel
cruise_v = move.cruise_v
accel_d = move.accel_r * move_d
cruise_d = move.cruise_r * move_d
decel_d = move.decel_r * move_d
for i in StepList:
# Calculate a virtual tower along the line of movement at
# the point closest to this stepper's tower.
towerx_d = self.towers[i][0] - origx
towery_d = self.towers[i][1] - origy
vt_startxy_d = (towerx_d*axes_d[0] + towery_d*axes_d[1])*inv_movexy_d
tangentxy_d2 = towerx_d**2 + towery_d**2 - vt_startxy_d**2
vt_arm_d = math.sqrt(self.arm_length2 - tangentxy_d2)
vt_startz = origz
# Generate steps
mcu_stepper = self.steppers[i].mcu_stepper
mcu_time = mcu_stepper.print_to_mcu_time(move_time)
if accel_d:
mcu_stepper.step_delta(
mcu_time, accel_d, move.start_v, accel,
vt_startz, vt_startxy_d, vt_arm_d, movez_r)
vt_startz += accel_d * movez_r
vt_startxy_d -= accel_d * movexy_r
mcu_time += move.accel_t
if cruise_d:
mcu_stepper.step_delta(
mcu_time, cruise_d, cruise_v, 0.,
vt_startz, vt_startxy_d, vt_arm_d, movez_r)
vt_startz += cruise_d * movez_r
vt_startxy_d -= cruise_d * movexy_r
mcu_time += move.cruise_t
if decel_d:
mcu_stepper.step_delta(
mcu_time, decel_d, cruise_v, -accel,
vt_startz, vt_startxy_d, vt_arm_d, movez_r)
######################################################################
# Matrix helper functions for 3x1 matrices
######################################################################
def matrix_cross(m1, m2):
return [m1[1] * m2[2] - m1[2] * m2[1],
m1[2] * m2[0] - m1[0] * m2[2],
m1[0] * m2[1] - m1[1] * m2[0]]
def matrix_dot(m1, m2):
return m1[0] * m2[0] + m1[1] * m2[1] + m1[2] * m2[2]
def matrix_magsq(m1):
return m1[0]**2 + m1[1]**2 + m1[2]**2
def matrix_sub(m1, m2):
return [m1[0] - m2[0], m1[1] - m2[1], m1[2] - m2[2]]
def matrix_mul(m1, s):
return [m1[0]*s, m1[1]*s, m1[2]*s]

212
klippy/extruder.py Normal file
View File

@@ -0,0 +1,212 @@
# Code for handling printer nozzle extruders
#
# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import math, logging
import stepper, heater, homing
EXTRUDE_DIFF_IGNORE = 1.02
class PrinterExtruder:
def __init__(self, printer, config):
self.config = config
self.heater = heater.PrinterHeater(printer, config)
self.stepper = stepper.PrinterStepper(printer, config, 'extruder')
self.nozzle_diameter = config.getfloat('nozzle_diameter', above=0.)
filament_diameter = config.getfloat(
'filament_diameter', minval=self.nozzle_diameter)
filament_area = math.pi * (filament_diameter * .5)**2
max_cross_section = config.getfloat(
'max_extrude_cross_section', 4. * self.nozzle_diameter**2
, above=0.)
self.max_extrude_ratio = max_cross_section / filament_area
self.max_e_dist = config.getfloat(
'max_extrude_only_distance', 50., minval=0.)
self.max_e_velocity = self.max_e_accel = None
self.pressure_advance = config.getfloat(
'pressure_advance', 0., minval=0.)
self.pressure_advance_lookahead_time = 0.
if self.pressure_advance:
self.pressure_advance_lookahead_time = config.getfloat(
'pressure_advance_lookahead_time', 0.010, minval=0.)
self.need_motor_enable = True
self.extrude_pos = 0.
def set_max_jerk(self, max_xy_halt_velocity, max_velocity, max_accel):
self.max_e_velocity = self.config.getfloat(
'max_extrude_only_velocity', max_velocity * self.max_extrude_ratio
, above=0.)
self.max_e_accel = self.config.getfloat(
'max_extrude_only_accel', max_accel * self.max_extrude_ratio
, above=0.)
self.stepper.set_max_jerk(9999999.9, 9999999.9)
def motor_off(self, move_time):
self.stepper.motor_enable(move_time, 0)
self.need_motor_enable = True
def check_move(self, move):
move.extrude_r = move.axes_d[3] / move.move_d
move.extrude_max_corner_v = 0.
if not self.heater.can_extrude:
raise homing.EndstopMoveError(
move.end_pos, "Extrude below minimum temp")
if not move.is_kinematic_move or move.extrude_r < 0.:
# Extrude only move (or retraction move) - limit accel and velocity
if abs(move.axes_d[3]) > self.max_e_dist:
raise homing.EndstopMoveError(
move.end_pos, "Extrude move too long")
inv_extrude_r = 1. / abs(move.extrude_r)
move.limit_speed(self.max_e_velocity * inv_extrude_r
, self.max_e_accel * inv_extrude_r)
elif (move.extrude_r > self.max_extrude_ratio
and move.axes_d[3] > self.nozzle_diameter*self.max_extrude_ratio):
logging.debug("Overextrude: %s vs %s" % (
move.extrude_r, self.max_extrude_ratio))
raise homing.EndstopMoveError(
move.end_pos, "Move exceeds maximum extrusion cross section")
def calc_junction(self, prev_move, move):
extrude = move.axes_d[3]
prev_extrude = prev_move.axes_d[3]
if extrude or prev_extrude:
if not extrude or not prev_extrude:
# Extrude move to non-extrude move - disable lookahead
return 0.
if ((move.extrude_r > prev_move.extrude_r * EXTRUDE_DIFF_IGNORE
or prev_move.extrude_r > move.extrude_r * EXTRUDE_DIFF_IGNORE)
and abs(move.move_d * prev_move.extrude_r - extrude) >= .001):
# Extrude ratio between moves is too different
return 0.
move.extrude_r = prev_move.extrude_r
return move.max_cruise_v2
def lookahead(self, moves, flush_count, lazy):
lookahead_t = self.pressure_advance_lookahead_time
if not lookahead_t:
return flush_count
# Calculate max_corner_v - the speed the head will accelerate
# to after cornering.
for i in range(flush_count):
move = moves[i]
if not move.decel_t:
continue
cruise_v = move.cruise_v
max_corner_v = 0.
sum_t = lookahead_t
for j in range(i+1, flush_count):
fmove = moves[j]
if not fmove.max_start_v2:
break
if fmove.cruise_v > max_corner_v:
if (not max_corner_v
and not fmove.accel_t and not fmove.cruise_t):
# Start timing after any full decel moves
continue
if sum_t >= fmove.accel_t:
max_corner_v = fmove.cruise_v
else:
max_corner_v = max(
max_corner_v, fmove.start_v + fmove.accel * sum_t)
if max_corner_v >= cruise_v:
break
sum_t -= fmove.accel_t + fmove.cruise_t + fmove.decel_t
if sum_t <= 0.:
break
else:
if lazy:
return i
move.extrude_max_corner_v = max_corner_v
return flush_count
def move(self, move_time, move):
if self.need_motor_enable:
self.stepper.motor_enable(move_time, 1)
self.need_motor_enable = False
axis_d = move.axes_d[3]
axis_r = abs(axis_d) / move.move_d
accel = move.accel * axis_r
start_v = move.start_v * axis_r
cruise_v = move.cruise_v * axis_r
end_v = move.end_v * axis_r
accel_t, cruise_t, decel_t = move.accel_t, move.cruise_t, move.decel_t
accel_d = move.accel_r * axis_d
cruise_d = move.cruise_r * axis_d
decel_d = move.decel_r * axis_d
retract_t = retract_d = retract_v = 0.
decel_v = cruise_v
# Update for pressure advance
start_pos = self.extrude_pos
if (axis_d >= 0. and (move.axes_d[0] or move.axes_d[1])
and self.pressure_advance):
# Increase accel_d and start_v when accelerating
pressure_advance = self.pressure_advance * move.extrude_r
prev_pressure_d = start_pos - move.start_pos[3]
if accel_d:
npd = move.cruise_v * pressure_advance
extra_accel_d = npd - prev_pressure_d
if extra_accel_d > 0.:
accel_d += extra_accel_d
start_v += extra_accel_d / accel_t
prev_pressure_d += extra_accel_d
# Update decel and retract parameters when decelerating
emcv = move.extrude_max_corner_v
if decel_d and emcv < move.cruise_v:
npd = max(emcv, move.end_v) * pressure_advance
extra_decel_d = prev_pressure_d - npd
if extra_decel_d > 0.:
extra_decel_v = extra_decel_d / decel_t
decel_v -= extra_decel_v
end_v -= extra_decel_v
if decel_v <= 0.:
# The entire decel phase is replaced with retraction
retract_t = decel_t
retract_d = -(end_v + decel_v) * 0.5 * decel_t
retract_v = -decel_v
decel_t = decel_d = 0.
elif end_v < 0.:
# Split decel phase into decel and retraction
retract_t = -end_v / accel
retract_d = -end_v * 0.5 * retract_t
decel_t -= retract_t
decel_d = decel_v * 0.5 * decel_t
else:
# There is still only a decel phase (no retraction)
decel_d -= extra_decel_d
# Prepare for steps
mcu_stepper = self.stepper.mcu_stepper
mcu_time = mcu_stepper.print_to_mcu_time(move_time)
# Acceleration steps
if accel_d:
mcu_stepper.step_const(mcu_time, start_pos, accel_d, start_v, accel)
start_pos += accel_d
mcu_time += accel_t
# Cruising steps
if cruise_d:
mcu_stepper.step_const(mcu_time, start_pos, cruise_d, cruise_v, 0.)
start_pos += cruise_d
mcu_time += cruise_t
# Deceleration steps
if decel_d:
mcu_stepper.step_const(mcu_time, start_pos, decel_d, decel_v, -accel)
start_pos += decel_d
mcu_time += decel_t
# Retraction steps
if retract_d:
mcu_stepper.step_const(
mcu_time, start_pos, -retract_d, retract_v, accel)
start_pos -= retract_d
self.extrude_pos = start_pos
# Dummy extruder class used when a printer has no extruder at all
class DummyExtruder:
def set_max_jerk(self, max_xy_halt_velocity, max_velocity, max_accel):
pass
def motor_off(self, move_time):
pass
def check_move(self, move):
raise homing.EndstopMoveError(
move.end_pos, "Extrude when no extruder present")
def calc_junction(self, prev_move, move):
return move.max_cruise_v2
def lookahead(self, moves, flush_count, lazy):
return flush_count

32
klippy/fan.py Normal file
View File

@@ -0,0 +1,32 @@
# Printer fan support
#
# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
FAN_MIN_TIME = 0.1
PWM_CYCLE_TIME = 0.010
class PrinterFan:
def __init__(self, printer, config):
self.last_fan_value = 0.
self.last_fan_time = 0.
self.kick_start_time = config.getfloat('kick_start_time', 0.1, minval=0.)
pin = config.get('pin')
hard_pwm = config.getint('hard_pwm', 0)
self.mcu_fan = printer.mcu.create_pwm(pin, PWM_CYCLE_TIME, hard_pwm, 0.)
# External commands
def set_speed(self, print_time, value):
value = max(0., min(1., value))
if value == self.last_fan_value:
return
mcu_time = self.mcu_fan.print_to_mcu_time(print_time)
mcu_time = max(self.last_fan_time + FAN_MIN_TIME, mcu_time)
if (value and value < 1.
and not self.last_fan_value and self.kick_start_time):
# Run fan at full speed for specified kick_start_time
self.mcu_fan.set_pwm(mcu_time, 1.)
mcu_time += self.kick_start_time
self.mcu_fan.set_pwm(mcu_time, value)
self.last_fan_time = mcu_time
self.last_fan_value = value

443
klippy/gcode.py Normal file
View File

@@ -0,0 +1,443 @@
# Parse gcode commands
#
# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import os, re, logging, collections
import homing
# Parse out incoming GCode and find and translate head movements
class GCodeParser:
RETRY_TIME = 0.100
def __init__(self, printer, fd, is_fileinput=False):
self.printer = printer
self.fd = fd
self.is_fileinput = is_fileinput
# Input handling
self.reactor = printer.reactor
self.is_processing_data = False
self.fd_handle = None
if not is_fileinput:
self.fd_handle = self.reactor.register_fd(self.fd, self.process_data)
self.input_commands = [""]
self.bytes_read = 0
self.input_log = collections.deque([], 50)
# Command handling
self.gcode_handlers = self.build_handlers(False)
self.is_printer_ready = False
self.need_ack = False
self.toolhead = self.heater_nozzle = self.heater_bed = self.fan = None
self.speed = 25.0
self.absolutecoord = self.absoluteextrude = True
self.base_position = [0.0, 0.0, 0.0, 0.0]
self.last_position = [0.0, 0.0, 0.0, 0.0]
self.homing_add = [0.0, 0.0, 0.0, 0.0]
self.axis2pos = {'X': 0, 'Y': 1, 'Z': 2, 'E': 3}
def build_handlers(self, is_ready):
handlers = self.all_handlers
if not is_ready:
handlers = [h for h in handlers
if getattr(self, 'cmd_'+h+'_when_not_ready', False)]
gcode_handlers = dict((h, getattr(self, 'cmd_'+h)) for h in handlers)
for h, f in gcode_handlers.items():
aliases = getattr(self, 'cmd_'+h+'_aliases', [])
gcode_handlers.update(dict([(a, f) for a in aliases]))
return gcode_handlers
def stats(self, eventtime):
return "gcodein=%d" % (self.bytes_read,)
def set_printer_ready(self, is_ready):
if self.is_printer_ready == is_ready:
return
self.is_printer_ready = is_ready
self.gcode_handlers = self.build_handlers(is_ready)
if not is_ready:
# Printer is shutdown (could be running in a background thread)
return
# Lookup printer components
self.toolhead = self.printer.objects.get('toolhead')
self.heater_nozzle = None
extruder = self.printer.objects.get('extruder')
if extruder:
self.heater_nozzle = extruder.heater
self.heater_bed = self.printer.objects.get('heater_bed')
self.fan = self.printer.objects.get('fan')
if self.is_fileinput and self.fd_handle is None:
self.fd_handle = self.reactor.register_fd(self.fd, self.process_data)
def motor_heater_off(self):
if self.toolhead is None:
return
self.toolhead.motor_off()
print_time = self.toolhead.get_last_move_time()
if self.heater_nozzle is not None:
self.heater_nozzle.set_temp(print_time, 0.)
if self.heater_bed is not None:
self.heater_bed.set_temp(print_time, 0.)
if self.fan is not None:
self.fan.set_speed(print_time, 0.)
def dump_debug(self):
logging.info("Dumping gcode input %d blocks" % (
len(self.input_log),))
for eventtime, data in self.input_log:
logging.info("Read %f: %s" % (eventtime, repr(data)))
# Parse input into commands
args_r = re.compile('([a-zA-Z_]+|[a-zA-Z*])')
def process_commands(self, eventtime):
while len(self.input_commands) > 1:
line = self.input_commands.pop(0)
# Ignore comments and leading/trailing spaces
line = origline = line.strip()
cpos = line.find(';')
if cpos >= 0:
line = line[:cpos]
# Break command into parts
parts = self.args_r.split(line)[1:]
params = dict((parts[i].upper(), parts[i+1].strip())
for i in range(0, len(parts), 2))
params['#original'] = origline
if parts and parts[0].upper() == 'N':
# Skip line number at start of command
del parts[:2]
if not parts:
self.cmd_default(params)
continue
params['#command'] = cmd = parts[0].upper() + parts[1].strip()
# Invoke handler for command
self.need_ack = True
handler = self.gcode_handlers.get(cmd, self.cmd_default)
try:
handler(params)
except error, e:
self.respond_error(str(e))
except:
logging.exception("Exception in command handler")
self.toolhead.force_shutdown()
self.respond_error('Internal error on command:"%s"' % (cmd,))
if self.is_fileinput:
self.printer.request_exit('exit_eof')
break
self.ack()
def process_data(self, eventtime):
data = os.read(self.fd, 4096)
self.input_log.append((eventtime, data))
self.bytes_read += len(data)
lines = data.split('\n')
lines[0] = self.input_commands.pop() + lines[0]
self.input_commands.extend(lines)
if self.is_processing_data:
if len(lines) <= 1:
return
if not self.is_fileinput and lines[0].strip().upper() == 'M112':
self.cmd_M112({})
self.reactor.unregister_fd(self.fd_handle)
self.fd_handle = None
return
self.is_processing_data = True
self.process_commands(eventtime)
self.is_processing_data = False
if self.fd_handle is None:
self.fd_handle = self.reactor.register_fd(self.fd, self.process_data)
if not data and self.is_fileinput:
self.motor_heater_off()
self.printer.request_exit('exit_eof')
# Response handling
def ack(self, msg=None):
if not self.need_ack or self.is_fileinput:
return
if msg:
os.write(self.fd, "ok %s\n" % (msg,))
else:
os.write(self.fd, "ok\n")
self.need_ack = False
def respond(self, msg):
logging.debug(msg)
if self.is_fileinput:
return
os.write(self.fd, msg+"\n")
def respond_info(self, msg):
lines = [l.strip() for l in msg.strip().split('\n')]
self.respond("// " + "\n// ".join(lines))
def respond_error(self, msg):
lines = msg.strip().split('\n')
if len(lines) > 1:
self.respond_info("\n".join(lines[:-1]))
self.respond('!! %s' % (lines[-1].strip(),))
# Parameter parsing helpers
def get_int(self, name, params, default=None):
if name in params:
try:
return int(params[name])
except ValueError:
raise error("Error on '%s': unable to parse %s" % (
params['#original'], params[name]))
if default is not None:
return default
raise error("Error on '%s': missing %s" % (params['#original'], name))
def get_float(self, name, params, default=None):
if name in params:
try:
return float(params[name])
except ValueError:
raise error("Error on '%s': unable to parse %s" % (
params['#original'], params[name]))
if default is not None:
return default
raise error("Error on '%s': missing %s" % (params['#original'], name))
# Temperature wrappers
def get_temp(self):
if not self.is_printer_ready:
return "T:0"
# T:XXX /YYY B:XXX /YYY
out = []
if self.heater_nozzle:
cur, target = self.heater_nozzle.get_temp()
out.append("T:%.1f /%.1f" % (cur, target))
if self.heater_bed:
cur, target = self.heater_bed.get_temp()
out.append("B:%.1f /%.1f" % (cur, target))
return " ".join(out)
def bg_temp(self, heater):
if self.is_fileinput:
return
eventtime = self.reactor.monotonic()
while self.is_printer_ready and heater.check_busy(eventtime):
print_time = self.toolhead.get_last_move_time()
self.respond(self.get_temp())
eventtime = self.reactor.pause(eventtime + 1.)
def set_temp(self, heater, params, wait=False):
temp = self.get_float('S', params, 0.)
if heater is None:
if temp > 0.:
self.respond_error("Heater not configured")
return
print_time = self.toolhead.get_last_move_time()
try:
heater.set_temp(print_time, temp)
except heater.error, e:
self.respond_error(str(e))
return
if wait:
self.bg_temp(heater)
def set_fan_speed(self, speed):
if self.fan is None:
if speed:
self.respond_info("Fan not configured")
return
print_time = self.toolhead.get_last_move_time()
self.fan.set_speed(print_time, speed)
# Individual command handlers
def cmd_default(self, params):
if not self.is_printer_ready:
self.respond_error(self.printer.get_state_message())
return
cmd = params.get('#command')
if not cmd:
logging.debug(params['#original'])
return
self.respond('echo:Unknown command:"%s"' % (cmd,))
all_handlers = [
'G1', 'G4', 'G20', 'G28', 'G90', 'G91', 'G92',
'M82', 'M83', 'M18', 'M105', 'M104', 'M109', 'M112', 'M114', 'M115',
'M140', 'M190', 'M106', 'M107', 'M206', 'M400',
'IGNORE', 'QUERY_ENDSTOPS', 'PID_TUNE', 'RESTART', 'FIRMWARE_RESTART',
'STATUS', 'HELP']
cmd_G1_aliases = ['G0']
def cmd_G1(self, params):
# Move
try:
for a, p in self.axis2pos.items():
if a in params:
v = float(params[a])
if (not self.absolutecoord
or (p>2 and not self.absoluteextrude)):
# value relative to position of last move
self.last_position[p] += v
else:
# value relative to base coordinate position
self.last_position[p] = v + self.base_position[p]
if 'F' in params:
speed = float(params['F']) / 60.
if speed <= 0.:
raise ValueError()
self.speed = speed
except ValueError, e:
self.last_position = self.toolhead.get_position()
raise error("Unable to parse move '%s'" % (params['#original'],))
try:
self.toolhead.move(self.last_position, self.speed)
except homing.EndstopError, e:
self.respond_error(str(e))
self.last_position = self.toolhead.get_position()
def cmd_G4(self, params):
# Dwell
if 'S' in params:
delay = self.get_float('S', params)
else:
delay = self.get_float('P', params, 0.) / 1000.
self.toolhead.dwell(delay)
def cmd_G20(self, params):
# Set units to inches
self.respond_error('Machine does not support G20 (inches) command')
def cmd_G28(self, params):
# Move to origin
axes = []
for axis in 'XYZ':
if axis in params:
axes.append(self.axis2pos[axis])
if not axes:
axes = [0, 1, 2]
homing_state = homing.Homing(self.toolhead, axes)
if self.is_fileinput:
homing_state.set_no_verify_retract()
try:
self.toolhead.home(homing_state)
except homing.EndstopError, e:
self.toolhead.motor_off()
self.respond_error(str(e))
return
newpos = self.toolhead.get_position()
for axis in homing_state.get_axes():
self.last_position[axis] = newpos[axis]
self.base_position[axis] = -self.homing_add[axis]
def cmd_G90(self, params):
# Use absolute coordinates
self.absolutecoord = True
def cmd_G91(self, params):
# Use relative coordinates
self.absolutecoord = False
def cmd_G92(self, params):
# Set position
offsets = { p: self.get_float(a, params)
for a, p in self.axis2pos.items() if a in params }
for p, offset in offsets.items():
self.base_position[p] = self.last_position[p] - offset
if not offsets:
self.base_position = list(self.last_position)
def cmd_M82(self, params):
# Use absolute distances for extrusion
self.absoluteextrude = True
def cmd_M83(self, params):
# Use relative distances for extrusion
self.absoluteextrude = False
cmd_M18_aliases = ["M84"]
def cmd_M18(self, params):
# Turn off motors
self.toolhead.motor_off()
cmd_M105_when_not_ready = True
def cmd_M105(self, params):
# Get Extruder Temperature
self.ack(self.get_temp())
def cmd_M104(self, params):
# Set Extruder Temperature
self.set_temp(self.heater_nozzle, params)
def cmd_M109(self, params):
# Set Extruder Temperature and Wait
self.set_temp(self.heater_nozzle, params, wait=True)
def cmd_M112(self, params):
# Emergency Stop
self.toolhead.force_shutdown()
cmd_M114_when_not_ready = True
def cmd_M114(self, params):
# Get Current Position
if self.toolhead is None:
self.cmd_default(params)
return
kinpos = self.toolhead.get_position()
self.respond("X:%.3f Y:%.3f Z:%.3f E:%.3f Count X:%.3f Y:%.3f Z:%.3f" % (
self.last_position[0], self.last_position[1],
self.last_position[2], self.last_position[3],
kinpos[0], kinpos[1], kinpos[2]))
cmd_M115_when_not_ready = True
def cmd_M115(self, params):
# Get Firmware Version and Capabilities
kw = {"FIRMWARE_NAME": "Klipper"
, "FIRMWARE_VERSION": self.printer.software_version}
self.ack(" ".join(["%s:%s" % (k, v) for k, v in kw.items()]))
def cmd_M140(self, params):
# Set Bed Temperature
self.set_temp(self.heater_bed, params)
def cmd_M190(self, params):
# Set Bed Temperature and Wait
self.set_temp(self.heater_bed, params, wait=True)
def cmd_M106(self, params):
# Set fan speed
self.set_fan_speed(self.get_float('S', params, 255.) / 255.)
def cmd_M107(self, params):
# Turn fan off
self.set_fan_speed(0.)
def cmd_M206(self, params):
# Set home offset
offsets = { p: self.get_float(a, params)
for a, p in self.axis2pos.items() if a in params }
for p, offset in offsets.items():
self.base_position[p] += self.homing_add[p] - offset
self.homing_add[p] = offset
def cmd_M400(self, params):
# Wait for current moves to finish
self.toolhead.wait_moves()
cmd_IGNORE_when_not_ready = True
cmd_IGNORE_aliases = ["G21", "M110", "M21"]
def cmd_IGNORE(self, params):
# Commands that are just silently accepted
pass
cmd_QUERY_ENDSTOPS_help = "Report on the status of each endstop"
cmd_QUERY_ENDSTOPS_aliases = ["M119"]
def cmd_QUERY_ENDSTOPS(self, params):
# Get Endstop Status
if self.is_fileinput:
return
try:
res = self.toolhead.query_endstops()
except self.printer.mcu.error, e:
self.respond_error(str(e))
return
self.respond(" ".join(["%s:%s" % (name, ["open", "TRIGGERED"][not not t])
for name, t in res]))
cmd_PID_TUNE_help = "Run PID Tuning"
cmd_PID_TUNE_aliases = ["M303"]
def cmd_PID_TUNE(self, params):
# Run PID tuning
heater = self.get_int('E', params, 0)
heater = {0: self.heater_nozzle, -1: self.heater_bed}[heater]
if heater is None:
self.respond_error("Heater not configured")
temp = self.get_float('S', params)
heater.start_auto_tune(temp)
self.bg_temp(heater)
def prep_restart(self):
if self.is_printer_ready:
self.respond_info("Preparing to restart...")
self.motor_heater_off()
self.toolhead.dwell(0.500)
self.toolhead.wait_moves()
cmd_RESTART_when_not_ready = True
cmd_RESTART_help = "Reload config file and restart host software"
def cmd_RESTART(self, params):
self.prep_restart()
self.printer.request_exit('restart')
cmd_FIRMWARE_RESTART_when_not_ready = True
cmd_FIRMWARE_RESTART_help = "Restart firmware, host, and reload config"
def cmd_FIRMWARE_RESTART(self, params):
self.prep_restart()
self.printer.request_exit('firmware_restart')
cmd_STATUS_when_not_ready = True
cmd_STATUS_help = "Report the printer status"
def cmd_STATUS(self, params):
msg = self.printer.get_state_message()
if self.is_printer_ready:
self.respond_info(msg)
else:
self.respond_error(msg)
cmd_HELP_when_not_ready = True
def cmd_HELP(self, params):
cmdhelp = []
if not self.is_printer_ready:
cmdhelp.append("Printer is not ready - not all commands available.")
cmdhelp.append("Available extended commands:")
for cmd in sorted(self.gcode_handlers):
desc = getattr(self, 'cmd_'+cmd+'_help', None)
if desc is not None:
cmdhelp.append("%-10s: %s" % (cmd, desc))
self.respond_info("\n".join(cmdhelp))
class error(Exception):
pass

310
klippy/heater.py Normal file
View File

@@ -0,0 +1,310 @@
# Printer heater support
#
# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import math, logging, threading
# Available sensors
Sensors = {
# Common thermistors and their Steinhart-Hart coefficients
"EPCOS 100K B57560G104F": (
"thermistor",
0.000722136308968056, 0.000216766566488498, 8.92935804531095e-08),
"ATC Semitec 104GT-2": (
"thermistor",
0.000809651054275124, 0.000211636030735685, 7.07420883993973e-08),
# Linear style conversion chips and their gain/offset
"AD595": ("linear", 300.0 / 3.022, 0.),
}
SAMPLE_TIME = 0.001
SAMPLE_COUNT = 8
REPORT_TIME = 0.300
PWM_CYCLE_TIME = 0.100
KELVIN_TO_CELCIUS = -273.15
MAX_HEAT_TIME = 5.0
AMBIENT_TEMP = 25.
PID_PARAM_BASE = 255.
class error(Exception):
pass
class PrinterHeater:
error = error
def __init__(self, printer, config):
self.name = config.section
sensor_params = config.getchoice('sensor_type', Sensors)
self.is_linear_sensor = (sensor_params[0] == 'linear')
if self.is_linear_sensor:
adc_voltage = config.getfloat('adc_voltage', 5., above=0.)
self.sensor_coef = sensor_params[1] * adc_voltage, sensor_params[2]
else:
pullup = config.getfloat('pullup_resistor', 4700., above=0.)
self.sensor_coef = sensor_params[1:] + (pullup,)
self.min_temp = config.getfloat('min_temp', minval=0.)
self.max_temp = config.getfloat('max_temp', above=self.min_temp)
self.min_extrude_temp = config.getfloat(
'min_extrude_temp', 170., minval=self.min_temp, maxval=self.max_temp)
self.max_power = config.getfloat('max_power', 1., above=0., maxval=1.)
self.can_extrude = (self.min_extrude_temp <= 0.
or printer.mcu.is_fileoutput())
self.lock = threading.Lock()
self.last_temp = 0.
self.last_temp_time = 0.
self.target_temp = 0.
algos = {'watermark': ControlBangBang, 'pid': ControlPID}
algo = config.getchoice('control', algos)
heater_pin = config.get('heater_pin')
sensor_pin = config.get('sensor_pin')
if algo is ControlBangBang and self.max_power == 1.:
self.mcu_pwm = printer.mcu.create_digital_out(
heater_pin, MAX_HEAT_TIME)
else:
self.mcu_pwm = printer.mcu.create_pwm(
heater_pin, PWM_CYCLE_TIME, 0, MAX_HEAT_TIME)
self.mcu_adc = printer.mcu.create_adc(sensor_pin)
adc_range = [self.calc_adc(self.min_temp), self.calc_adc(self.max_temp)]
self.mcu_adc.set_minmax(SAMPLE_TIME, SAMPLE_COUNT,
minval=min(adc_range), maxval=max(adc_range))
self.mcu_adc.set_adc_callback(REPORT_TIME, self.adc_callback)
self.control = algo(self, config)
# pwm caching
self.next_pwm_time = 0.
self.last_pwm_value = 0
def set_pwm(self, read_time, value):
if self.target_temp <= 0.:
value = 0.
if ((read_time < self.next_pwm_time or not self.last_pwm_value)
and abs(value - self.last_pwm_value) < 0.05):
# No significant change in value - can suppress update
return
pwm_time = read_time + REPORT_TIME + SAMPLE_TIME*SAMPLE_COUNT
self.next_pwm_time = pwm_time + 0.75 * MAX_HEAT_TIME
self.last_pwm_value = value
logging.debug("%s: pwm=%.3f@%.3f (from %.3f@%.3f [%.3f])" % (
self.name, value, pwm_time,
self.last_temp, self.last_temp_time, self.target_temp))
self.mcu_pwm.set_pwm(pwm_time, value)
# Temperature calculation
def calc_temp(self, adc):
if self.is_linear_sensor:
gain, offset = self.sensor_coef
return adc * gain + offset
c1, c2, c3, pullup = self.sensor_coef
r = pullup * adc / (1.0 - adc)
ln_r = math.log(r)
temp_inv = c1 + c2*ln_r + c3*math.pow(ln_r, 3)
return 1.0/temp_inv + KELVIN_TO_CELCIUS
def calc_adc(self, temp):
if temp is None:
return None
if self.is_linear_sensor:
gain, offset = self.sensor_coef
return (temp - offset) / gain
c1, c2, c3, pullup = self.sensor_coef
temp -= KELVIN_TO_CELCIUS
temp_inv = 1./temp
y = (c1 - temp_inv) / (2*c3)
x = math.sqrt(math.pow(c2 / (3.*c3), 3.) + math.pow(y, 2.))
r = math.exp(math.pow(x-y, 1./3.) - math.pow(x+y, 1./3.))
return r / (pullup + r)
def adc_callback(self, read_time, read_value):
temp = self.calc_temp(read_value)
with self.lock:
self.last_temp = temp
self.last_temp_time = read_time
self.can_extrude = (temp >= self.min_extrude_temp)
self.control.adc_callback(read_time, temp)
#logging.debug("temp: %.3f %f = %f" % (read_time, read_value, temp))
# External commands
def set_temp(self, print_time, degrees):
if degrees and (degrees < self.min_temp or degrees > self.max_temp):
raise error("Requested temperature (%.1f) out of range (%.1f:%.1f)"
% (degrees, self.min_temp, self.max_temp))
with self.lock:
self.target_temp = degrees
def get_temp(self):
with self.lock:
return self.last_temp, self.target_temp
def check_busy(self, eventtime):
with self.lock:
return self.control.check_busy(eventtime)
def start_auto_tune(self, temp):
with self.lock:
self.control = ControlAutoTune(self, self.control, temp)
######################################################################
# Bang-bang control algo
######################################################################
class ControlBangBang:
def __init__(self, heater, config):
self.heater = heater
self.max_delta = config.getfloat('max_delta', 2.0, above=0.)
self.heating = False
def adc_callback(self, read_time, temp):
if self.heating and temp >= self.heater.target_temp+self.max_delta:
self.heating = False
elif not self.heating and temp <= self.heater.target_temp-self.max_delta:
self.heating = True
if self.heating:
self.heater.set_pwm(read_time, self.heater.max_power)
else:
self.heater.set_pwm(read_time, 0.)
def check_busy(self, eventtime):
return self.heater.last_temp < self.heater.target_temp-self.max_delta
######################################################################
# Proportional Integral Derivative (PID) control algo
######################################################################
class ControlPID:
def __init__(self, heater, config):
self.heater = heater
self.Kp = config.getfloat('pid_Kp') / PID_PARAM_BASE
self.Ki = config.getfloat('pid_Ki') / PID_PARAM_BASE
self.Kd = config.getfloat('pid_Kd') / PID_PARAM_BASE
self.min_deriv_time = config.getfloat('pid_deriv_time', 2., above=0.)
imax = config.getfloat('pid_integral_max', heater.max_power, minval=0.)
self.temp_integ_max = imax / self.Ki
self.prev_temp = AMBIENT_TEMP
self.prev_temp_time = 0.
self.prev_temp_deriv = 0.
self.prev_temp_integ = 0.
def adc_callback(self, read_time, temp):
time_diff = read_time - self.prev_temp_time
# Calculate change of temperature
temp_diff = temp - self.prev_temp
if time_diff >= self.min_deriv_time:
temp_deriv = temp_diff / time_diff
else:
temp_deriv = (self.prev_temp_deriv * (self.min_deriv_time-time_diff)
+ temp_diff) / self.min_deriv_time
# Calculate accumulated temperature "error"
temp_err = self.heater.target_temp - temp
temp_integ = self.prev_temp_integ + temp_err * time_diff
temp_integ = max(0., min(self.temp_integ_max, temp_integ))
# Calculate output
co = self.Kp*temp_err + self.Ki*temp_integ - self.Kd*temp_deriv
#logging.debug("pid: %f@%.3f -> diff=%f deriv=%f err=%f integ=%f co=%d" % (
# temp, read_time, temp_diff, temp_deriv, temp_err, temp_integ, co))
bounded_co = max(0., min(self.heater.max_power, co))
self.heater.set_pwm(read_time, bounded_co)
# Store state for next measurement
self.prev_temp = temp
self.prev_temp_time = read_time
self.prev_temp_deriv = temp_deriv
if co == bounded_co:
self.prev_temp_integ = temp_integ
def check_busy(self, eventtime):
temp_diff = self.heater.target_temp - self.heater.last_temp
return abs(temp_diff) > 1. or abs(self.prev_temp_deriv) > 0.1
######################################################################
# Ziegler-Nichols PID autotuning
######################################################################
TUNE_PID_DELTA = 5.0
class ControlAutoTune:
def __init__(self, heater, old_control, target_temp):
self.heater = heater
self.old_control = old_control
self.target_temp = target_temp
self.heating = False
self.peaks = []
self.peak = 0.
self.peak_time = 0.
def adc_callback(self, read_time, temp):
if self.heating and temp >= self.target_temp:
self.heating = False
self.check_peaks()
elif not self.heating and temp <= self.target_temp - TUNE_PID_DELTA:
self.heating = True
self.check_peaks()
if self.heating:
self.heater.set_pwm(read_time, self.heater.max_power)
if temp < self.peak:
self.peak = temp
self.peak_time = read_time
else:
self.heater.set_pwm(read_time, 0.)
if temp > self.peak:
self.peak = temp
self.peak_time = read_time
def check_peaks(self):
self.peaks.append((self.peak, self.peak_time))
if self.heating:
self.peak = 9999999.
else:
self.peak = -9999999.
if len(self.peaks) < 4:
return
temp_diff = self.peaks[-1][0] - self.peaks[-2][0]
time_diff = self.peaks[-1][1] - self.peaks[-3][1]
max_power = self.heater.max_power
Ku = 4. * (2. * max_power) / (abs(temp_diff) * math.pi)
Tu = time_diff
Kp = 0.6 * Ku
Ti = 0.5 * Tu
Td = 0.125 * Tu
Ki = Kp / Ti
Kd = Kp * Td
logging.info("Autotune: raw=%f/%f Ku=%f Tu=%f Kp=%f Ki=%f Kd=%f" % (
temp_diff, max_power, Ku, Tu,
Kp * PID_PARAM_BASE, Ki * PID_PARAM_BASE, Kd * PID_PARAM_BASE))
def check_busy(self, eventtime):
if self.heating or len(self.peaks) < 12:
return True
self.heater.control = self.old_control
return False
######################################################################
# Tuning information test
######################################################################
class ControlBumpTest:
def __init__(self, heater, old_control, target_temp):
self.heater = heater
self.old_control = old_control
self.target_temp = target_temp
self.temp_samples = {}
self.pwm_samples = {}
self.state = 0
def set_pwm(self, read_time, value):
self.pwm_samples[read_time + 2*REPORT_TIME] = value
self.heater.set_pwm(read_time, value)
def adc_callback(self, read_time, temp):
self.temp_samples[read_time] = temp
if not self.state:
self.set_pwm(read_time, 0.)
if len(self.temp_samples) >= 20:
self.state += 1
elif self.state == 1:
if temp < self.target_temp:
self.set_pwm(read_time, self.heater.max_power)
return
self.set_pwm(read_time, 0.)
self.state += 1
elif self.state == 2:
self.set_pwm(read_time, 0.)
if temp <= (self.target_temp + AMBIENT_TEMP) / 2.:
self.dump_stats()
self.state += 1
def dump_stats(self):
out = ["%.3f %.1f %d" % (time, temp, self.pwm_samples.get(time, -1.))
for time, temp in sorted(self.temp_samples.items())]
f = open("/tmp/heattest.txt", "wb")
f.write('\n'.join(out))
f.close()
def check_busy(self, eventtime):
if self.state < 3:
return True
self.heater.control = self.old_control
return False

61
klippy/homing.py Normal file
View File

@@ -0,0 +1,61 @@
# Code for state tracking during homing operations
#
# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import logging
class Homing:
def __init__(self, toolhead, changed_axes):
self.toolhead = toolhead
self.changed_axes = changed_axes
self.verify_retract = True
def set_no_verify_retract(self):
self.verify_retract = False
def set_axes(self, axes):
self.changed_axes = axes
def get_axes(self):
return self.changed_axes
def _fill_coord(self, coord):
# Fill in any None entries in 'coord' with current toolhead position
thcoord = list(self.toolhead.get_position())
for i in range(len(coord)):
if coord[i] is not None:
thcoord[i] = coord[i]
return thcoord
def retract(self, newpos, speed):
self.toolhead.move(self._fill_coord(newpos), speed)
def home(self, forcepos, movepos, steppers, speed, second_home=False):
# Alter kinematics class to think printer is at forcepos
self.toolhead.set_position(self._fill_coord(forcepos))
# Start homing and issue move
print_time = self.toolhead.get_last_move_time()
endstops = []
for s in steppers:
es = s.enable_endstop_checking(print_time, s.step_dist / speed)
endstops.append((s, es, s.mcu_stepper.get_mcu_position()))
self.toolhead.move(self._fill_coord(movepos), speed)
move_end_print_time = self.toolhead.get_last_move_time()
self.toolhead.reset_print_time()
for s, es, last_pos in endstops:
es.home_finalize(es.print_to_mcu_time(move_end_print_time))
# Wait for endstops to trigger
for s, es, last_pos in endstops:
try:
es.home_wait()
except es.error, e:
raise EndstopError("Failed to home stepper %s: %s" % (
s.name, str(e)))
post_home_pos = s.mcu_stepper.get_mcu_position()
if second_home and self.verify_retract and last_pos == post_home_pos:
raise EndstopError("Endstop %s still triggered after retract" % (
s.name,))
def set_homed_position(self, pos):
self.toolhead.set_position(self._fill_coord(pos))
class EndstopError(Exception):
pass
def EndstopMoveError(pos, msg="Move out of range"):
return EndstopError("%s: %.3f %.3f %.3f [%.3f]" % (
msg, pos[0], pos[1], pos[2], pos[3]))

354
klippy/klippy.py Normal file
View File

@@ -0,0 +1,354 @@
#!/usr/bin/env python
# Main code for host side printer firmware
#
# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import sys, optparse, ConfigParser, logging, time, threading
import gcode, toolhead, util, mcu, fan, heater, extruder, reactor, queuelogger
import msgproto
message_ready = "Printer is ready"
message_startup = """
The klippy host software is attempting to connect. Please
retry in a few moments.
Printer is not ready
"""
message_restart = """
Once the underlying issue is corrected, use the "RESTART"
command to reload the config and restart the host software.
Printer is halted
"""
message_protocol_error = """
This type of error is frequently caused by running an older
version of the firmware on the micro-controller (fix by
recompiling and flashing the firmware).
Once the underlying issue is corrected, use the "RESTART"
command to reload the config and restart the host software.
Protocol error connecting to printer
"""
message_mcu_connect_error = """
Once the underlying issue is corrected, use the
"FIRMWARE_RESTART" command to reset the firmware, reload the
config, and restart the host software.
Error configuring printer
"""
message_shutdown = """
Once the underlying issue is corrected, use the
"FIRMWARE_RESTART" command to reset the firmware, reload the
config, and restart the host software.
Printer is shutdown
"""
class ConfigWrapper:
error = ConfigParser.Error
class sentinel:
pass
def __init__(self, printer, section):
self.printer = printer
self.section = section
def get_wrapper(self, parser, option, default
, minval=None, maxval=None, above=None, below=None):
if (default is not self.sentinel
and not self.printer.fileconfig.has_option(self.section, option)):
return default
self.printer.all_config_options[
(self.section.lower(), option.lower())] = 1
try:
v = parser(self.section, option)
except self.error, e:
raise
except:
raise self.error("Unable to parse option '%s' in section '%s'" % (
option, self.section))
if minval is not None and v < minval:
raise self.error(
"Option '%s' in section '%s' must have minimum of %s" % (
option, self.section, minval))
if maxval is not None and v > maxval:
raise self.error(
"Option '%s' in section '%s' must have maximum of %s" % (
option, self.section, maxval))
if above is not None and v <= above:
raise self.error(
"Option '%s' in section '%s' must be above %s" % (
option, self.section, above))
if below is not None and v >= below:
raise self.error(
"Option '%s' in section '%s' must be below %s" % (
option, self.section, below))
return v
def get(self, option, default=sentinel):
return self.get_wrapper(self.printer.fileconfig.get, option, default)
def getint(self, option, default=sentinel, minval=None, maxval=None):
return self.get_wrapper(
self.printer.fileconfig.getint, option, default, minval, maxval)
def getfloat(self, option, default=sentinel
, minval=None, maxval=None, above=None, below=None):
return self.get_wrapper(
self.printer.fileconfig.getfloat, option, default
, minval, maxval, above, below)
def getboolean(self, option, default=sentinel):
return self.get_wrapper(
self.printer.fileconfig.getboolean, option, default)
def getchoice(self, option, choices, default=sentinel):
c = self.get(option, default)
if c not in choices:
raise self.error(
"Option '%s' in section '%s' is not a valid choice" % (
option, self.section))
return choices[c]
def getsection(self, section):
return ConfigWrapper(self.printer, section)
class ConfigLogger():
def __init__(self, cfg, bglogger):
self.lines = ["===== Config file ====="]
cfg.write(self)
self.lines.append("=======================")
data = "\n".join(self.lines)
logging.info(data)
bglogger.set_rollover_info("config", data)
def write(self, data):
self.lines.append(data.strip())
class Printer:
def __init__(self, conffile, input_fd, startup_state
, is_fileinput=False, version="?", bglogger=None):
self.conffile = conffile
self.startup_state = startup_state
self.software_version = version
self.bglogger = bglogger
if bglogger is not None:
bglogger.set_rollover_info("config", None)
self.reactor = reactor.Reactor()
self.objects = {}
self.gcode = gcode.GCodeParser(self, input_fd, is_fileinput)
self.stats_timer = self.reactor.register_timer(self.stats)
self.connect_timer = self.reactor.register_timer(
self.connect, self.reactor.NOW)
self.all_config_options = {}
self.need_dump_debug = False
self.state_message = message_startup
self.debugoutput = self.dictionary = None
self.run_result = None
self.fileconfig = None
self.mcu = None
def set_fileoutput(self, debugoutput, dictionary):
self.debugoutput = debugoutput
self.dictionary = dictionary
def stats(self, eventtime, force_output=False):
if self.need_dump_debug:
# Call dump_debug here so it is executed in the main thread
self.gcode.dump_debug()
self.need_dump_debug = False
toolhead = self.objects.get('toolhead')
if toolhead is None or self.mcu is None:
return
is_active, thstats = toolhead.stats(eventtime)
if not is_active and not force_output:
return
out = []
out.append(self.gcode.stats(eventtime))
out.append(thstats)
out.append(self.mcu.stats(eventtime))
logging.info("Stats %.1f: %s" % (eventtime, ' '.join(out)))
return eventtime + 1.
def load_config(self):
self.fileconfig = ConfigParser.RawConfigParser()
res = self.fileconfig.read(self.conffile)
if not res:
raise ConfigParser.Error("Unable to open config file %s" % (
self.conffile,))
if self.bglogger is not None:
ConfigLogger(self.fileconfig, self.bglogger)
self.mcu = mcu.MCU(self, ConfigWrapper(self, 'mcu'))
if self.debugoutput is not None:
self.mcu.connect_file(self.debugoutput, self.dictionary)
if self.fileconfig.has_section('extruder'):
self.objects['extruder'] = extruder.PrinterExtruder(
self, ConfigWrapper(self, 'extruder'))
if self.fileconfig.has_section('fan'):
self.objects['fan'] = fan.PrinterFan(
self, ConfigWrapper(self, 'fan'))
if self.fileconfig.has_section('heater_bed'):
self.objects['heater_bed'] = heater.PrinterHeater(
self, ConfigWrapper(self, 'heater_bed'))
self.objects['toolhead'] = toolhead.ToolHead(
self, ConfigWrapper(self, 'printer'))
# Validate that there are no undefined parameters in the config file
valid_sections = dict([(s, 1) for s, o in self.all_config_options])
for section in self.fileconfig.sections():
section = section.lower()
if section not in valid_sections:
raise ConfigParser.Error("Unknown config file section '%s'" % (
section,))
for option in self.fileconfig.options(section):
option = option.lower()
if (section, option) not in self.all_config_options:
raise ConfigParser.Error(
"Unknown option '%s' in section '%s'" % (
option, section))
def connect(self, eventtime):
try:
self.load_config()
if self.debugoutput is None:
self.reactor.update_timer(self.stats_timer, self.reactor.NOW)
self.mcu.connect()
self.gcode.set_printer_ready(True)
self.state_message = message_ready
except ConfigParser.Error, e:
logging.exception("Config error")
self.state_message = "%s%s" % (str(e), message_restart)
self.reactor.update_timer(self.stats_timer, self.reactor.NEVER)
except msgproto.error, e:
logging.exception("Protocol error")
self.state_message = "%s%s" % (str(e), message_protocol_error)
self.reactor.update_timer(self.stats_timer, self.reactor.NEVER)
except mcu.error, e:
logging.exception("MCU error during connect")
self.state_message = "%s%s" % (str(e), message_mcu_connect_error)
self.reactor.update_timer(self.stats_timer, self.reactor.NEVER)
except:
logging.exception("Unhandled exception during connect")
self.state_message = "Internal error during connect.%s" % (
message_restart)
self.reactor.update_timer(self.stats_timer, self.reactor.NEVER)
self.reactor.unregister_timer(self.connect_timer)
return self.reactor.NEVER
def run(self):
systime = time.time()
monotime = self.reactor.monotonic()
logging.info("Start printer at %s (%.1f %.1f)" % (
time.asctime(time.localtime(systime)), systime, monotime))
try:
self.reactor.run()
except:
logging.exception("Unhandled exception during run")
return
return self.run_result
def get_state_message(self):
return self.state_message
def note_shutdown(self, msg):
if self.state_message == message_ready:
self.need_dump_debug = True
self.state_message = "Firmware shutdown: %s%s" % (
msg, message_shutdown)
self.gcode.set_printer_ready(False)
def note_mcu_error(self, msg):
self.state_message = "%s%s" % (msg, message_restart)
self.gcode.set_printer_ready(False)
self.gcode.motor_heater_off()
def disconnect(self):
try:
if self.mcu is not None:
self.stats(self.reactor.monotonic(), force_output=True)
self.mcu.disconnect()
except:
logging.exception("Unhandled exception during disconnect")
def firmware_restart(self):
try:
if self.mcu is not None:
self.stats(self.reactor.monotonic(), force_output=True)
self.mcu.microcontroller_restart()
self.mcu.disconnect()
except:
logging.exception("Unhandled exception during firmware_restart")
def get_startup_state(self):
return self.startup_state
def request_exit(self, result="exit"):
self.run_result = result
self.reactor.end()
######################################################################
# Startup
######################################################################
def read_dictionary(filename):
dfile = open(filename, 'rb')
dictionary = dfile.read()
dfile.close()
return dictionary
def main():
usage = "%prog [options] <config file>"
opts = optparse.OptionParser(usage)
opts.add_option("-o", "--debugoutput", dest="outputfile",
help="write output to file instead of to serial port")
opts.add_option("-i", "--debuginput", dest="inputfile",
help="read commands from file instead of from tty port")
opts.add_option("-I", "--input-tty", dest="inputtty", default='/tmp/printer',
help="input tty name (default is /tmp/printer)")
opts.add_option("-l", "--logfile", dest="logfile",
help="write log to file instead of stderr")
opts.add_option("-v", action="store_true", dest="verbose",
help="enable debug messages")
opts.add_option("-d", dest="read_dictionary",
help="file to read for mcu protocol dictionary")
options, args = opts.parse_args()
if len(args) != 1:
opts.error("Incorrect number of arguments")
conffile = args[0]
input_fd = debuginput = debugoutput = bglogger = None
debuglevel = logging.INFO
if options.verbose:
debuglevel = logging.DEBUG
if options.inputfile:
debuginput = open(options.inputfile, 'rb')
input_fd = debuginput.fileno()
else:
input_fd = util.create_pty(options.inputtty)
if options.outputfile:
debugoutput = open(options.outputfile, 'wb')
if options.logfile:
bglogger = queuelogger.setup_bg_logging(options.logfile, debuglevel)
else:
logging.basicConfig(level=debuglevel)
logging.info("Starting Klippy...")
software_version = util.get_git_version()
if bglogger is not None:
lines = ["Args: %s" % (sys.argv,),
"Git version: %s" % (repr(software_version),),
"CPU: %s" % (util.get_cpu_info(),),
"Python: %s" % (repr(sys.version),)]
lines = "\n".join(lines)
logging.info(lines)
bglogger.set_rollover_info('versions', lines)
# Start firmware
res = 'startup'
while 1:
is_fileinput = debuginput is not None
printer = Printer(
conffile, input_fd, res, is_fileinput, software_version, bglogger)
if debugoutput:
proto_dict = read_dictionary(options.read_dictionary)
printer.set_fileoutput(debugoutput, proto_dict)
res = printer.run()
if res == 'restart':
printer.disconnect()
time.sleep(1.)
logging.info("Restarting printer")
continue
elif res == 'firmware_restart':
printer.firmware_restart()
time.sleep(1.)
logging.info("Restarting printer")
continue
elif res == 'exit_eof':
printer.disconnect()
break
if bglogger is not None:
bglogger.stop()
if __name__ == '__main__':
main()

108
klippy/list.h Normal file
View File

@@ -0,0 +1,108 @@
#ifndef __LIST_H
#define __LIST_H
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
/****************************************************************
* list - Double linked lists
****************************************************************/
struct list_node {
struct list_node *next, *prev;
};
struct list_head {
struct list_node root;
};
static inline void
list_init(struct list_head *h)
{
h->root.prev = h->root.next = &h->root;
}
static inline int
list_empty(const struct list_head *h)
{
return h->root.next == &h->root;
}
static inline void
list_del(struct list_node *n)
{
struct list_node *prev = n->prev;
struct list_node *next = n->next;
next->prev = prev;
prev->next = next;
}
static inline void
__list_add(struct list_node *n, struct list_node *prev, struct list_node *next)
{
next->prev = n;
n->next = next;
n->prev = prev;
prev->next = n;
}
static inline void
list_add_after(struct list_node *n, struct list_node *prev)
{
__list_add(n, prev, prev->next);
}
static inline void
list_add_before(struct list_node *n, struct list_node *next)
{
__list_add(n, next->prev, next);
}
static inline void
list_add_head(struct list_node *n, struct list_head *h)
{
list_add_after(n, &h->root);
}
static inline void
list_add_tail(struct list_node *n, struct list_head *h)
{
list_add_before(n, &h->root);
}
static inline void
list_join_tail(struct list_head *add, struct list_head *h)
{
if (!list_empty(add)) {
struct list_node *prev = h->root.prev;
struct list_node *next = &h->root;
struct list_node *first = add->root.next;
struct list_node *last = add->root.prev;
first->prev = prev;
prev->next = first;
last->next = next;
next->prev = last;
}
}
#define list_next_entry(pos, member) \
container_of((pos)->member.next, typeof(*pos), member)
#define list_first_entry(head, type, member) \
container_of((head)->root.next, type, member)
#define list_for_each_entry(pos, head, member) \
for (pos = list_first_entry((head), typeof(*pos), member) \
; &pos->member != &(head)->root \
; pos = list_next_entry(pos, member))
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_first_entry((head), typeof(*pos), member) \
, n = list_next_entry(pos, member) \
; &pos->member != &(head)->root \
; pos = n, n = list_next_entry(n, member))
#endif // list.h

662
klippy/mcu.py Normal file
View File

@@ -0,0 +1,662 @@
# Multi-processor safe interface to micro-controller
#
# Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import sys, os, zlib, logging, math
import serialhdl, pins, chelper
class error(Exception):
pass
def parse_pin_extras(pin, can_pullup=False):
pullup = invert = 0
if can_pullup and pin.startswith('^'):
pullup = 1
pin = pin[1:].strip()
if pin.startswith('!'):
invert = 1
pin = pin[1:].strip()
return pin, pullup, invert
STEPCOMPRESS_ERROR_RET = -989898989
class MCU_stepper:
def __init__(self, mcu, step_pin, dir_pin):
self._mcu = mcu
self._oid = mcu.create_oid(self)
self._step_pin, pullup, self._invert_step = parse_pin_extras(step_pin)
self._dir_pin, pullup, self._invert_dir = parse_pin_extras(dir_pin)
self._commanded_pos = 0
self._step_dist = self._inv_step_dist = 1.
self._velocity_factor = self._accel_factor = 0.
self._mcu_position_offset = 0
self._mcu_freq = self._min_stop_interval = 0.
self._reset_cmd = self._get_position_cmd = None
self._ffi_lib = self._stepqueue = None
self.print_to_mcu_time = mcu.print_to_mcu_time
def set_min_stop_interval(self, min_stop_interval):
self._min_stop_interval = min_stop_interval
def set_step_distance(self, step_dist):
self._step_dist = step_dist
self._inv_step_dist = 1. / step_dist
def build_config(self):
self._mcu_freq = self._mcu.get_mcu_freq()
self._velocity_factor = 1. / (self._mcu_freq * self._step_dist)
self._accel_factor = 1. / (self._mcu_freq**2 * self._step_dist)
max_error = self._mcu.get_max_stepper_error()
min_stop_interval = max(0., self._min_stop_interval - max_error)
self._mcu.add_config_cmd(
"config_stepper oid=%d step_pin=%s dir_pin=%s"
" min_stop_interval=TICKS(%.9f) invert_step=%d" % (
self._oid, self._step_pin, self._dir_pin,
min_stop_interval, self._invert_step))
self._mcu.register_stepper(self)
step_cmd = self._mcu.lookup_command(
"queue_step oid=%c interval=%u count=%hu add=%hi")
dir_cmd = self._mcu.lookup_command(
"set_next_step_dir oid=%c dir=%c")
self._reset_cmd = self._mcu.lookup_command(
"reset_step_clock oid=%c clock=%u")
self._get_position_cmd = self._mcu.lookup_command(
"stepper_get_position oid=%c")
ffi_main, self._ffi_lib = chelper.get_ffi()
max_error = int(max_error * self._mcu_freq)
self._stepqueue = ffi_main.gc(self._ffi_lib.stepcompress_alloc(
max_error, step_cmd.msgid, dir_cmd.msgid,
self._invert_dir, self._oid),
self._ffi_lib.stepcompress_free)
def get_oid(self):
return self._oid
def set_position(self, pos):
if pos >= 0.:
steppos = int(pos * self._inv_step_dist + 0.5)
else:
steppos = int(pos * self._inv_step_dist - 0.5)
self._mcu_position_offset += self._commanded_pos - steppos
self._commanded_pos = steppos
def get_commanded_position(self):
return self._commanded_pos * self._step_dist
def get_mcu_position(self):
return self._commanded_pos + self._mcu_position_offset
def note_homing_start(self, homing_clock):
ret = self._ffi_lib.stepcompress_set_homing(
self._stepqueue, homing_clock)
if ret:
raise error("Internal error in stepcompress")
def note_homing_finalized(self):
ret = self._ffi_lib.stepcompress_set_homing(self._stepqueue, 0)
if ret:
raise error("Internal error in stepcompress")
ret = self._ffi_lib.stepcompress_reset(self._stepqueue, 0)
if ret:
raise error("Internal error in stepcompress")
def note_homing_triggered(self):
params = self._mcu.serial.send_with_response(
self._get_position_cmd.encode(self._oid),
'stepper_position', self._oid)
pos = params['pos']
if self._invert_dir:
pos = -pos
self._mcu_position_offset = pos - self._commanded_pos
def reset_step_clock(self, mcu_time):
clock = int(mcu_time * self._mcu_freq)
ret = self._ffi_lib.stepcompress_reset(self._stepqueue, clock)
if ret:
raise error("Internal error in stepcompress")
data = (self._reset_cmd.msgid, self._oid, clock & 0xffffffff)
ret = self._ffi_lib.stepcompress_queue_msg(
self._stepqueue, data, len(data))
if ret:
raise error("Internal error in stepcompress")
def step(self, mcu_time, sdir):
clock = mcu_time * self._mcu_freq
ret = self._ffi_lib.stepcompress_push(self._stepqueue, clock, sdir)
if ret:
raise error("Internal error in stepcompress")
if sdir:
self._commanded_pos += 1
else:
self._commanded_pos -= 1
def step_const(self, mcu_time, start_pos, dist, start_v, accel):
inv_step_dist = self._inv_step_dist
step_offset = self._commanded_pos - start_pos * inv_step_dist
count = self._ffi_lib.stepcompress_push_const(
self._stepqueue, mcu_time * self._mcu_freq, step_offset,
dist * inv_step_dist, start_v * self._velocity_factor,
accel * self._accel_factor)
if count == STEPCOMPRESS_ERROR_RET:
raise error("Internal error in stepcompress")
self._commanded_pos += count
def step_delta(self, mcu_time, dist, start_v, accel
, height_base, startxy_d, arm_d, movez_r):
inv_step_dist = self._inv_step_dist
height = self._commanded_pos - height_base * inv_step_dist
count = self._ffi_lib.stepcompress_push_delta(
self._stepqueue, mcu_time * self._mcu_freq, dist * inv_step_dist,
start_v * self._velocity_factor, accel * self._accel_factor,
height, startxy_d * inv_step_dist, arm_d * inv_step_dist, movez_r)
if count == STEPCOMPRESS_ERROR_RET:
raise error("Internal error in stepcompress")
self._commanded_pos += count
class MCU_endstop:
error = error
RETRY_QUERY = 1.000
def __init__(self, mcu, pin):
self._mcu = mcu
self._oid = mcu.create_oid(self)
self._steppers = []
self._pin, self._pullup, self._invert = parse_pin_extras(
pin, can_pullup=True)
self._cmd_queue = mcu.alloc_command_queue()
self._home_cmd = self._query_cmd = None
self._homing = False
self._min_query_time = self._mcu_freq = 0.
self._next_query_clock = self._home_timeout_clock = 0
self._retry_query_ticks = 0
self._last_state = {}
mcu.add_init_callback(self._init_callback)
self.print_to_mcu_time = mcu.print_to_mcu_time
def add_stepper(self, stepper):
self._steppers.append(stepper)
def build_config(self):
self._mcu_freq = self._mcu.get_mcu_freq()
self._mcu.add_config_cmd(
"config_end_stop oid=%d pin=%s pull_up=%d stepper_count=%d" % (
self._oid, self._pin, self._pullup, len(self._steppers)))
self._retry_query_ticks = int(self._mcu_freq * self.RETRY_QUERY)
self._home_cmd = self._mcu.lookup_command(
"end_stop_home oid=%c clock=%u rest_ticks=%u pin_value=%c")
self._query_cmd = self._mcu.lookup_command("end_stop_query oid=%c")
self._mcu.register_msg(self._handle_end_stop_state, "end_stop_state"
, self._oid)
def _init_callback(self):
set_cmd = self._mcu.lookup_command(
"end_stop_set_stepper oid=%c pos=%c stepper_oid=%c")
for i, s in enumerate(self._steppers):
msg = set_cmd.encode(self._oid, i, s.get_oid())
self._mcu.send(msg, cq=self._cmd_queue)
def home_start(self, mcu_time, rest_time):
clock = int(mcu_time * self._mcu_freq)
rest_ticks = int(rest_time * self._mcu_freq)
self._homing = True
self._min_query_time = self._mcu.monotonic()
self._next_query_clock = clock + self._retry_query_ticks
msg = self._home_cmd.encode(
self._oid, clock, rest_ticks, 1 ^ self._invert)
self._mcu.send(msg, reqclock=clock, cq=self._cmd_queue)
for s in self._steppers:
s.note_homing_start(clock)
def home_finalize(self, mcu_time):
for s in self._steppers:
s.note_homing_finalized()
self._home_timeout_clock = int(mcu_time * self._mcu_freq)
def home_wait(self):
eventtime = self._mcu.monotonic()
while self._check_busy(eventtime):
eventtime = self._mcu.pause(eventtime + 0.1)
def _handle_end_stop_state(self, params):
logging.debug("end_stop_state %s" % (params,))
self._last_state = params
def _check_busy(self, eventtime):
# Check if need to send an end_stop_query command
if self._mcu.is_fileoutput():
return False
last_sent_time = self._last_state.get('#sent_time', -1.)
if last_sent_time >= self._min_query_time:
if not self._homing:
return False
if not self._last_state.get('homing', 0):
for s in self._steppers:
s.note_homing_triggered()
self._homing = False
return False
if (self._mcu.serial.get_clock(last_sent_time)
> self._home_timeout_clock):
# Timeout - disable endstop checking
msg = self._home_cmd.encode(self._oid, 0, 0, 0)
self._mcu.send(msg, reqclock=0, cq=self._cmd_queue)
raise error("Timeout during endstop homing")
if self._mcu.is_shutdown:
raise error("MCU is shutdown")
last_clock, last_clock_time = self._mcu.get_last_clock()
if last_clock >= self._next_query_clock:
self._next_query_clock = last_clock + self._retry_query_ticks
msg = self._query_cmd.encode(self._oid)
self._mcu.send(msg, cq=self._cmd_queue)
return True
def query_endstop(self, mcu_time):
clock = int(mcu_time * self._mcu_freq)
self._homing = False
self._min_query_time = self._mcu.monotonic()
self._next_query_clock = clock
def query_endstop_wait(self):
eventtime = self._mcu.monotonic()
while self._check_busy(eventtime):
eventtime = self._mcu.pause(eventtime + 0.1)
return self._last_state.get('pin', self._invert) ^ self._invert
class MCU_digital_out:
def __init__(self, mcu, pin, max_duration):
self._mcu = mcu
self._oid = mcu.create_oid(self)
pin, pullup, self._invert = parse_pin_extras(pin)
self._last_clock = 0
self._last_value = None
self._mcu_freq = 0.
self._cmd_queue = mcu.alloc_command_queue()
mcu.add_config_cmd(
"config_digital_out oid=%d pin=%s default_value=%d"
" max_duration=TICKS(%f)" % (
self._oid, pin, self._invert, max_duration))
self._set_cmd = None
self.print_to_mcu_time = mcu.print_to_mcu_time
def build_config(self):
self._mcu_freq = self._mcu.get_mcu_freq()
self._set_cmd = self._mcu.lookup_command(
"schedule_digital_out oid=%c clock=%u value=%c")
def set_digital(self, mcu_time, value):
clock = int(mcu_time * self._mcu_freq)
msg = self._set_cmd.encode(self._oid, clock, value ^ self._invert)
self._mcu.send(msg, minclock=self._last_clock, reqclock=clock
, cq=self._cmd_queue)
self._last_clock = clock
self._last_value = value
def get_last_setting(self):
return self._last_value
def set_pwm(self, mcu_time, value):
dval = 0
if value >= 0.5:
dval = 1
self.set_digital(mcu_time, dval)
class MCU_pwm:
PWM_MAX = 255.
def __init__(self, mcu, pin, cycle_time, hard_cycle_ticks, max_duration):
self._mcu = mcu
self._hard_cycle_ticks = hard_cycle_ticks
self._oid = mcu.create_oid(self)
pin, pullup, self._invert = parse_pin_extras(pin)
self._last_clock = 0
self._mcu_freq = 0.
self._cmd_queue = mcu.alloc_command_queue()
if hard_cycle_ticks:
mcu.add_config_cmd(
"config_pwm_out oid=%d pin=%s cycle_ticks=%d default_value=%d"
" max_duration=TICKS(%f)" % (
self._oid, pin, hard_cycle_ticks, self._invert,
max_duration))
else:
mcu.add_config_cmd(
"config_soft_pwm_out oid=%d pin=%s cycle_ticks=TICKS(%f)"
" default_value=%d max_duration=TICKS(%f)" % (
self._oid, pin, cycle_time, self._invert, max_duration))
self._set_cmd = None
self.print_to_mcu_time = mcu.print_to_mcu_time
def build_config(self):
self._mcu_freq = self._mcu.get_mcu_freq()
if self._hard_cycle_ticks:
self._set_cmd = self._mcu.lookup_command(
"schedule_pwm_out oid=%c clock=%u value=%c")
else:
self._set_cmd = self._mcu.lookup_command(
"schedule_soft_pwm_out oid=%c clock=%u value=%c")
def set_pwm(self, mcu_time, value):
clock = int(mcu_time * self._mcu_freq)
if self._invert:
value = 1. - value
value = int(value * self.PWM_MAX + 0.5)
msg = self._set_cmd.encode(self._oid, clock, value)
self._mcu.send(msg, minclock=self._last_clock, reqclock=clock
, cq=self._cmd_queue)
self._last_clock = clock
class MCU_adc:
def __init__(self, mcu, pin):
self._mcu = mcu
self._oid = mcu.create_oid(self)
self._min_sample = self._max_sample = 0.
self._sample_time = self._report_time = 0.
self._sample_count = 0
self._report_clock = 0
self._callback = None
self._inv_max_adc = 0.
self._mcu_freq = 0.
self._cmd_queue = mcu.alloc_command_queue()
mcu.add_config_cmd("config_analog_in oid=%d pin=%s" % (self._oid, pin))
self._query_cmd = None
mcu.add_init_callback(self._init_callback)
self._query_cmd = None
def build_config(self):
self._mcu_freq = self._mcu.get_mcu_freq()
self._query_cmd = self._mcu.lookup_command(
"query_analog_in oid=%c clock=%u sample_ticks=%u sample_count=%c"
" rest_ticks=%u min_value=%hu max_value=%hu")
def set_minmax(self, sample_time, sample_count, minval=0., maxval=1.):
self._sample_time = sample_time
self._sample_count = sample_count
self._min_sample = minval
self._max_sample = maxval
def _init_callback(self):
if not self._sample_count:
return
last_clock, last_clock_time = self._mcu.get_last_clock()
clock = last_clock + int(self._mcu_freq * (1.0 + self._oid * 0.01)) # XXX
sample_ticks = int(self._sample_time * self._mcu_freq)
mcu_adc_max = self._mcu.serial.msgparser.get_constant_float("ADC_MAX")
max_adc = self._sample_count * mcu_adc_max
self._inv_max_adc = 1.0 / max_adc
self._report_clock = int(self._report_time * self._mcu_freq)
self._mcu.register_msg(self._handle_analog_in_state, "analog_in_state"
, self._oid)
min_sample = int(self._min_sample * max_adc)
max_sample = min(0xffff, int(math.ceil(self._max_sample * max_adc)))
msg = self._query_cmd.encode(
self._oid, clock, sample_ticks, self._sample_count
, self._report_clock, min_sample, max_sample)
self._mcu.send(msg, reqclock=clock, cq=self._cmd_queue)
def _handle_analog_in_state(self, params):
last_value = params['value'] * self._inv_max_adc
next_clock = self._mcu.serial.translate_clock(params['next_clock'])
last_read_time = (next_clock - self._report_clock) / self._mcu_freq
if self._callback is not None:
self._callback(last_read_time, last_value)
def set_adc_callback(self, report_time, callback):
self._report_time = report_time
self._callback = callback
class MCU:
error = error
COMM_TIMEOUT = 3.5
def __init__(self, printer, config):
self._printer = printer
# Serial port
baud = config.getint('baud', 250000)
self._serialport = config.get('serial', '/dev/ttyS0')
self.serial = serialhdl.SerialReader(
printer.reactor, self._serialport, baud)
self.is_shutdown = False
self._shutdown_msg = ""
self._is_fileoutput = False
self._timeout_timer = printer.reactor.register_timer(
self.timeout_handler)
rmethods = {m: m for m in ['arduino', 'command', 'rpi_usb']}
self._restart_method = config.getchoice(
'restart_method', rmethods, 'arduino')
# Config building
if printer.bglogger is not None:
printer.bglogger.set_rollover_info("mcu", None)
self._config_error = config.error
self._emergency_stop_cmd = self._reset_cmd = None
self._oids = []
self._config_cmds = []
self._config_crc = None
self._init_callbacks = []
self._pin_map = config.get('pin_map', None)
self._custom = config.get('custom', '')
# Move command queuing
ffi_main, self._ffi_lib = chelper.get_ffi()
self._max_stepper_error = config.getfloat(
'max_stepper_error', 0.000025, minval=0.)
self._steppers = []
self._steppersync = None
# Print time to clock epoch calculations
self._print_start_time = 0.
self._mcu_freq = 0.
# Stats
self._stats_sumsq_base = 0.
self._mcu_tick_avg = 0.
self._mcu_tick_stddev = 0.
def handle_mcu_stats(self, params):
count = params['count']
tick_sum = params['sum']
c = 1.0 / (count * self._mcu_freq)
self._mcu_tick_avg = tick_sum * c
tick_sumsq = params['sumsq'] * self._stats_sumsq_base
self._mcu_tick_stddev = c * math.sqrt(count*tick_sumsq - tick_sum**2)
def handle_shutdown(self, params):
if self.is_shutdown:
return
self.is_shutdown = True
self._shutdown_msg = params['#msg']
logging.info("%s: %s" % (params['#name'], self._shutdown_msg))
pst = self._print_start_time
logging.info("Clock last synchronized at %.6f (%d)" % (
pst, int(pst * self._mcu_freq)))
self.serial.dump_debug()
self._printer.note_shutdown(self._shutdown_msg)
# Connection phase
def _check_restart(self, reason):
if self._printer.get_startup_state() == 'firmware_restart':
return
logging.info("Attempting automated firmware restart: %s" % (reason,))
self._printer.request_exit('firmware_restart')
self._printer.reactor.pause(self._printer.reactor.monotonic() + 2.000)
raise error("Attempt firmware restart failed")
def connect(self):
if not self._is_fileoutput:
if (self._restart_method == 'rpi_usb'
and not os.path.exists(self._serialport)):
# Try toggling usb power
self._check_restart("enable power")
self.serial.connect()
self._printer.reactor.update_timer(
self._timeout_timer, self.monotonic() + self.COMM_TIMEOUT)
self._mcu_freq = self.serial.msgparser.get_constant_float('CLOCK_FREQ')
self._stats_sumsq_base = self.serial.msgparser.get_constant_float(
'STATS_SUMSQ_BASE')
self._emergency_stop_cmd = self.lookup_command("emergency_stop")
try:
self._reset_cmd = self.lookup_command("reset")
except self.serial.msgparser.error, e:
pass
self.register_msg(self.handle_shutdown, 'shutdown')
self.register_msg(self.handle_shutdown, 'is_shutdown')
self.register_msg(self.handle_mcu_stats, 'stats')
self._build_config()
self._send_config()
def connect_file(self, debugoutput, dictionary, pace=False):
self._is_fileoutput = True
self.serial.connect_file(debugoutput, dictionary)
if not pace:
def dummy_set_print_start_time(eventtime):
pass
def dummy_get_print_buffer_time(eventtime, last_move_end):
return 1.250
self.set_print_start_time = dummy_set_print_start_time
self.get_print_buffer_time = dummy_get_print_buffer_time
def timeout_handler(self, eventtime):
last_clock, last_clock_time = self.serial.get_last_clock()
timeout = last_clock_time + self.COMM_TIMEOUT
if eventtime < timeout:
return timeout
logging.info("Timeout with firmware (eventtime=%f last_status=%f)" % (
eventtime, last_clock_time))
self._printer.note_mcu_error("Lost communication with firmware")
return self._printer.reactor.NEVER
def disconnect(self):
self.serial.disconnect()
if self._steppersync is not None:
self._ffi_lib.steppersync_free(self._steppersync)
self._steppersync = None
def stats(self, eventtime):
return "%s mcu_task_avg=%.06f mcu_task_stddev=%.06f" % (
self.serial.stats(eventtime),
self._mcu_tick_avg, self._mcu_tick_stddev)
def force_shutdown(self):
self.send(self._emergency_stop_cmd.encode())
def microcontroller_restart(self):
reactor = self._printer.reactor
if self._restart_method == 'rpi_usb':
logging.info("Attempting a microcontroller reset via rpi usb power")
self.disconnect()
chelper.run_hub_ctrl(0)
reactor.pause(reactor.monotonic() + 2.000)
chelper.run_hub_ctrl(1)
return
if self._restart_method == 'command':
last_clock, last_clock_time = self.serial.get_last_clock()
eventtime = reactor.monotonic()
if (self._reset_cmd is None
or eventtime > last_clock_time + self.COMM_TIMEOUT):
logging.info("Unable to issue reset command")
return
# Attempt reset via command
logging.info("Attempting a microcontroller reset command")
self.send(self._reset_cmd.encode())
reactor.pause(reactor.monotonic() + 0.015)
self.disconnect()
return
# Attempt reset via arduino mechanism
logging.info("Attempting a microcontroller reset")
self.disconnect()
serialhdl.arduino_reset(self._serialport, reactor)
def is_fileoutput(self):
return self._is_fileoutput
# Configuration phase
def _add_custom(self):
for line in self._custom.split('\n'):
line = line.strip()
cpos = line.find('#')
if cpos >= 0:
line = line[:cpos].strip()
if not line:
continue
self.add_config_cmd(line)
def _build_config(self):
# Build config commands
for oid in self._oids:
oid.build_config()
self._add_custom()
self._config_cmds.insert(0, "allocate_oids count=%d" % (
len(self._oids),))
# Resolve pin names
mcu = self.serial.msgparser.get_constant('MCU')
pnames = pins.get_pin_map(mcu, self._pin_map)
updated_cmds = []
for cmd in self._config_cmds:
try:
updated_cmds.append(pins.update_command(
cmd, self._mcu_freq, pnames))
except:
raise self._config_error("Unable to translate pin name: %s" % (
cmd,))
self._config_cmds = updated_cmds
# Calculate config CRC
self._config_crc = zlib.crc32('\n'.join(self._config_cmds)) & 0xffffffff
self.add_config_cmd("finalize_config crc=%d" % (self._config_crc,))
def _send_config(self):
msg = self.create_command("get_config")
if self._is_fileoutput:
config_params = {
'is_config': 0, 'move_count': 500, 'crc': self._config_crc}
else:
config_params = self.serial.send_with_response(msg, 'config')
if not config_params['is_config']:
if self._restart_method == 'rpi_usb':
# Only configure mcu after usb power reset
self._check_restart("full reset before config")
# Send config commands
logging.info("Sending printer configuration...")
for c in self._config_cmds:
self.send(self.create_command(c))
if not self._is_fileoutput:
config_params = self.serial.send_with_response(msg, 'config')
if not config_params['is_config']:
if self.is_shutdown:
raise error("Firmware error during config: %s" % (
self._shutdown_msg,))
raise error("Unable to configure printer")
elif self._printer.get_startup_state() == 'firmware_restart':
raise error("Failed automated reset of micro-controller")
if self._config_crc != config_params['crc']:
self._check_restart("CRC mismatch")
raise error("Printer CRC does not match config")
move_count = config_params['move_count']
logging.info("Configured (%d moves)" % (move_count,))
if self._printer.bglogger is not None:
msgparser = self.serial.msgparser
info = [
"Configured (%d moves)" % (move_count,),
"Loaded %d commands (%s)" % (
len(msgparser.messages_by_id), msgparser.version),
"MCU config: %s" % (" ".join(
["%s=%s" % (k, v) for k, v in msgparser.config.items()]))]
self._printer.bglogger.set_rollover_info("mcu", "\n".join(info))
stepqueues = tuple(s._stepqueue for s in self._steppers)
self._steppersync = self._ffi_lib.steppersync_alloc(
self.serial.serialqueue, stepqueues, len(stepqueues), move_count)
for cb in self._init_callbacks:
cb()
# Config creation helpers
def create_oid(self, oid):
self._oids.append(oid)
return len(self._oids) - 1
def add_config_cmd(self, cmd):
self._config_cmds.append(cmd)
def add_init_callback(self, callback):
self._init_callbacks.append(callback)
def register_msg(self, cb, msg, oid=None):
self.serial.register_callback(cb, msg, oid)
def register_stepper(self, stepper):
self._steppers.append(stepper)
def alloc_command_queue(self):
return self.serial.alloc_command_queue()
def lookup_command(self, msgformat):
return self.serial.msgparser.lookup_command(msgformat)
def create_command(self, msg):
return self.serial.msgparser.create_command(msg)
# Wrappers for mcu object creation
def create_stepper(self, step_pin, dir_pin):
return MCU_stepper(self, step_pin, dir_pin)
def create_endstop(self, pin):
return MCU_endstop(self, pin)
def create_digital_out(self, pin, max_duration=2.):
return MCU_digital_out(self, pin, max_duration)
def create_pwm(self, pin, cycle_time, hard_cycle_ticks=0, max_duration=2.):
if hard_cycle_ticks < 0:
return MCU_digital_out(self, pin, max_duration)
return MCU_pwm(self, pin, cycle_time, hard_cycle_ticks, max_duration)
def create_adc(self, pin):
return MCU_adc(self, pin)
# Clock syncing
def set_print_start_time(self, eventtime):
clock = self.serial.get_clock(eventtime)
logging.debug("Synchronizing mcu clock at %.6f to %d" % (
eventtime, clock))
est_mcu_time = clock / self._mcu_freq
self._print_start_time = est_mcu_time
def get_print_buffer_time(self, eventtime, print_time):
if self.is_shutdown:
return 0.
mcu_time = print_time + self._print_start_time
est_mcu_time = self.serial.get_clock(eventtime) / self._mcu_freq
return mcu_time - est_mcu_time
def print_to_mcu_time(self, print_time):
return print_time + self._print_start_time
def get_mcu_freq(self):
return self._mcu_freq
def get_last_clock(self):
return self.serial.get_last_clock()
def get_max_stepper_error(self):
return self._max_stepper_error
# Move command queuing
def send(self, cmd, minclock=0, reqclock=0, cq=None):
self.serial.send(cmd, minclock, reqclock, cq=cq)
def flush_moves(self, print_time):
if self._steppersync is None:
return
mcu_time = print_time + self._print_start_time
clock = int(mcu_time * self._mcu_freq)
ret = self._ffi_lib.steppersync_flush(self._steppersync, clock)
if ret:
raise error("Internal error in stepcompress")
def pause(self, waketime):
return self._printer.reactor.pause(waketime)
def monotonic(self):
return self._printer.reactor.monotonic()
def __del__(self):
self.disconnect()

328
klippy/msgproto.py Normal file
View File

@@ -0,0 +1,328 @@
# Protocol definitions for firmware communication
#
# Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import json, zlib, logging
DefaultMessages = {
0: "identify_response offset=%u data=%.*s",
1: "identify offset=%u count=%c",
}
MESSAGE_MIN = 5
MESSAGE_MAX = 64
MESSAGE_HEADER_SIZE = 2
MESSAGE_TRAILER_SIZE = 3
MESSAGE_POS_LEN = 0
MESSAGE_POS_SEQ = 1
MESSAGE_TRAILER_CRC = 3
MESSAGE_TRAILER_SYNC = 1
MESSAGE_PAYLOAD_MAX = MESSAGE_MAX - MESSAGE_MIN
MESSAGE_SEQ_MASK = 0x0f
MESSAGE_DEST = 0x10
MESSAGE_SYNC = '\x7E'
class error(Exception):
pass
def crc16_ccitt(buf):
crc = 0xffff
for data in buf:
data = ord(data)
data ^= crc & 0xff
data ^= (data & 0x0f) << 4
crc = ((data << 8) | (crc >> 8)) ^ (data >> 4) ^ (data << 3)
crc = chr(crc >> 8) + chr(crc & 0xff)
return crc
class PT_uint32:
is_int = 1
max_length = 5
signed = 0
def encode(self, out, v):
if v >= 0xc000000 or v < -0x4000000: out.append((v>>28) & 0x7f | 0x80)
if v >= 0x180000 or v < -0x80000: out.append((v>>21) & 0x7f | 0x80)
if v >= 0x3000 or v < -0x1000: out.append((v>>14) & 0x7f | 0x80)
if v >= 0x60 or v < -0x20: out.append((v>>7) & 0x7f | 0x80)
out.append(v & 0x7f)
def parse(self, s, pos):
c = s[pos]
pos += 1
v = c & 0x7f
if (c & 0x60) == 0x60:
v |= -0x20
while c & 0x80:
c = s[pos]
pos += 1
v = (v<<7) | (c & 0x7f)
if not self.signed:
v = int(v & 0xffffffff)
return v, pos
class PT_int32(PT_uint32):
signed = 1
class PT_uint16(PT_uint32):
max_length = 3
class PT_int16(PT_int32):
signed = 1
max_length = 3
class PT_byte(PT_uint32):
max_length = 2
class PT_string:
is_int = 0
max_length = 64
def encode(self, out, v):
out.append(len(v))
out.extend(bytearray(v))
def parse(self, s, pos):
l = s[pos]
return str(bytearray(s[pos+1:pos+l+1])), pos+l+1
class PT_progmem_buffer(PT_string):
pass
class PT_buffer(PT_string):
pass
MessageTypes = {
'%u': PT_uint32(), '%i': PT_int32(),
'%hu': PT_uint16(), '%hi': PT_int16(),
'%c': PT_byte(),
'%s': PT_string(), '%.*s': PT_progmem_buffer(), '%*s': PT_buffer(),
}
# Update the message format to be compatible with python's % operator
def convert_msg_format(msgformat):
mf = msgformat.replace('%c', '%u')
mf = mf.replace('%.*s', '%s').replace('%*s', '%s')
return mf
class MessageFormat:
def __init__(self, msgid, msgformat):
self.msgid = msgid
self.msgformat = msgformat
self.debugformat = convert_msg_format(msgformat)
parts = msgformat.split()
self.name = parts[0]
argparts = [arg.split('=') for arg in parts[1:]]
self.param_types = [MessageTypes[fmt] for name, fmt in argparts]
self.param_names = [(name, MessageTypes[fmt]) for name, fmt in argparts]
self.name_to_type = dict(self.param_names)
def encode(self, *params):
out = []
out.append(self.msgid)
for i, t in enumerate(self.param_types):
t.encode(out, params[i])
return out
def encode_by_name(self, **params):
out = []
out.append(self.msgid)
for name, t in self.param_names:
t.encode(out, params[name])
return out
def parse(self, s, pos):
pos += 1
out = {}
for name, t in self.param_names:
v, pos = t.parse(s, pos)
out[name] = v
return out, pos
def format_params(self, params):
out = []
for name, t in self.param_names:
v = params[name]
if not t.is_int:
v = repr(v)
out.append(v)
return self.debugformat % tuple(out)
class OutputFormat:
name = '#output'
def __init__(self, msgid, msgformat):
self.msgid = msgid
self.msgformat = msgformat
self.debugformat = convert_msg_format(msgformat)
self.param_types = []
args = msgformat
while 1:
pos = args.find('%')
if pos < 0:
break
if pos+1 >= len(args) or args[pos+1] != '%':
for i in range(4):
t = MessageTypes.get(args[pos:pos+1+i])
if t is not None:
self.param_types.append(t)
break
else:
raise error("Invalid output format for '%s'" % (msg,))
args = args[pos+1:]
def parse(self, s, pos):
pos += 1
out = []
for t in self.param_types:
v, pos = t.parse(s, pos)
if not t.is_int:
v = repr(v)
out.append(v)
outmsg = self.debugformat % tuple(out)
return {'#msg': outmsg}, pos
def format_params(self, params):
return "#output %s" % (params['#msg'],)
class UnknownFormat:
name = '#unknown'
def parse(self, s, pos):
msgid = s[pos]
msg = str(bytearray(s))
return {'#msgid': msgid, '#msg': msg}, len(s)-MESSAGE_TRAILER_SIZE
def format_params(self, params):
return "#unknown %s" % (repr(params['#msg']),)
class MessageParser:
error = error
def __init__(self):
self.unknown = UnknownFormat()
self.messages_by_id = {}
self.messages_by_name = {}
self.static_strings = []
self.config = {}
self.version = ""
self.raw_identify_data = ""
self._init_messages(DefaultMessages, DefaultMessages.keys())
def check_packet(self, s):
if len(s) < MESSAGE_MIN:
return 0
msglen = ord(s[MESSAGE_POS_LEN])
if msglen < MESSAGE_MIN or msglen > MESSAGE_MAX:
return -1
msgseq = ord(s[MESSAGE_POS_SEQ])
if (msgseq & ~MESSAGE_SEQ_MASK) != MESSAGE_DEST:
return -1
if len(s) < msglen:
# Need more data
return 0
if s[msglen-MESSAGE_TRAILER_SYNC] != MESSAGE_SYNC:
return -1
msgcrc = s[msglen-MESSAGE_TRAILER_CRC:msglen-MESSAGE_TRAILER_CRC+2]
crc = crc16_ccitt(s[:msglen-MESSAGE_TRAILER_SIZE])
if crc != msgcrc:
#logging.debug("got crc %s vs %s" % (repr(crc), repr(msgcrc)))
return -1
return msglen
def dump(self, s):
msgseq = s[MESSAGE_POS_SEQ]
out = ["seq: %02x" % (msgseq,)]
pos = MESSAGE_HEADER_SIZE
while 1:
msgid = s[pos]
mid = self.messages_by_id.get(msgid, self.unknown)
params, pos = mid.parse(s, pos)
out.append(mid.format_params(params))
if pos >= len(s)-MESSAGE_TRAILER_SIZE:
break
return out
def format_params(self, params):
name = params.get('#name')
mid = self.messages_by_name.get(name)
if mid is not None:
return mid.format_params(params)
msg = params.get('#msg')
if msg is not None:
return "%s %s" % (name, msg)
return str(params)
def parse(self, s):
msgid = s[MESSAGE_HEADER_SIZE]
mid = self.messages_by_id.get(msgid, self.unknown)
params, pos = mid.parse(s, MESSAGE_HEADER_SIZE)
if pos != len(s)-MESSAGE_TRAILER_SIZE:
raise error("Extra data at end of message")
params['#name'] = mid.name
static_string_id = params.get('static_string_id')
if static_string_id is not None:
params['#msg'] = self.static_strings[static_string_id]
return params
def encode(self, seq, cmd):
msglen = MESSAGE_MIN + len(cmd)
seq = (seq & MESSAGE_SEQ_MASK) | MESSAGE_DEST
out = [chr(msglen), chr(seq), cmd]
out.append(crc16_ccitt(''.join(out)))
out.append(MESSAGE_SYNC)
return ''.join(out)
def _parse_buffer(self, value):
tval = int(value, 16)
out = []
for i in range(len(value)/2):
out.append(tval & 0xff)
tval >>= 8
out.reverse()
return ''.join([chr(i) for i in out])
def lookup_command(self, msgformat):
parts = msgformat.strip().split()
msgname = parts[0]
mp = self.messages_by_name.get(msgname)
if mp is None:
raise error("Unknown command: %s" % (msgname,))
if msgformat != mp.msgformat:
raise error("Command format mismatch: %s vs %s" % (
msgformat, mp.msgformat))
return mp
def create_command(self, msg):
parts = msg.strip().split()
if not parts:
return ""
msgname = parts[0]
mp = self.messages_by_name.get(msgname)
if mp is None:
raise error("Unknown command: %s" % (msgname,))
try:
argparts = dict(arg.split('=', 1) for arg in parts[1:])
for name, value in argparts.items():
t = mp.name_to_type[name]
if t.is_int:
tval = int(value, 0)
else:
tval = self._parse_buffer(value)
argparts[name] = tval
except:
#traceback.print_exc()
raise error("Unable to extract params from: %s" % (msgname,))
try:
cmd = mp.encode_by_name(**argparts)
except:
#traceback.print_exc()
raise error("Unable to encode: %s" % (msgname,))
return cmd
def _init_messages(self, messages, parsers):
for msgid, msgformat in messages.items():
msgid = int(msgid)
if msgid not in parsers:
self.messages_by_id[msgid] = OutputFormat(msgid, msgformat)
continue
msg = MessageFormat(msgid, msgformat)
self.messages_by_id[msgid] = msg
self.messages_by_name[msg.name] = msg
def process_identify(self, data, decompress=True):
if decompress:
data = zlib.decompress(data)
self.raw_identify_data = data
data = json.loads(data)
messages = data.get('messages')
commands = data.get('commands')
responses = data.get('responses')
self._init_messages(messages, commands+responses)
self.static_strings = data.get('static_strings', [])
self.config.update(data.get('config', {}))
self.version = data.get('version', '')
def get_constant(self, name):
try:
return self.config[name]
except KeyError:
raise error("Firmware constant '%s' not found" % (name,))
def get_constant_float(self, name):
try:
return float(self.config[name])
except ValueError:
raise error("Firmware constant '%s' not a float" % (name,))
except KeyError:
raise error("Firmware constant '%s' not found" % (name,))

45
klippy/parsedump.py Executable file
View File

@@ -0,0 +1,45 @@
#!/usr/bin/env python
# Script to parse a serial port data dump
#
# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import os, sys, logging
import msgproto
def read_dictionary(filename):
dfile = open(filename, 'rb')
dictionary = dfile.read()
dfile.close()
return dictionary
def main():
dict_filename, data_filename = sys.argv[1:]
dictionary = read_dictionary(dict_filename)
mp = msgproto.MessageParser()
mp.process_identify(dictionary, decompress=False)
f = open(data_filename, 'rb')
fd = f.fileno()
data = ""
while 1:
newdata = os.read(fd, 4096)
if not newdata:
break
data += newdata
while 1:
l = mp.check_packet(data)
if l == 0:
break
if l < 0:
logging.error("Invalid data")
data = data[-l:]
continue
msgs = mp.dump(bytearray(data[:l]))
sys.stdout.write('\n'.join(msgs[1:]) + '\n')
data = data[l:]
if __name__ == '__main__':
main()

111
klippy/pins.py Normal file
View File

@@ -0,0 +1,111 @@
# Pin name to pin number definitions
#
# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import re
def port_pins(port_count, bit_count=8):
pins = {}
for port in range(port_count):
portchr = chr(65 + port)
if portchr == 'I':
continue
for portbit in range(bit_count):
pins['P%c%d' % (portchr, portbit)] = port * bit_count + portbit
return pins
MCU_PINS = {
"atmega168": port_pins(4), "atmega644p": port_pins(4),
"at90usb1286": port_pins(5),
"atmega1280": port_pins(12), "atmega2560": port_pins(12),
"sam3x8e": port_pins(4, 32)
}
######################################################################
# Arduino mappings
######################################################################
Arduino_standard = [
"PD0", "PD1", "PD2", "PD3", "PD4", "PD5", "PD6", "PD7", "PB0", "PB1",
"PB2", "PB3", "PB4", "PB5", "PC0", "PC1", "PC2", "PC3", "PC4", "PC5",
]
Arduino_analog_standard = [
"PC0", "PC1", "PC2", "PC3", "PC4", "PC5", "PE0", "PE1",
]
Arduino_mega = [
"PE0", "PE1", "PE4", "PE5", "PG5", "PE3", "PH3", "PH4", "PH5", "PH6",
"PB4", "PB5", "PB6", "PB7", "PJ1", "PJ0", "PH1", "PH0", "PD3", "PD2",
"PD1", "PD0", "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7",
"PC7", "PC6", "PC5", "PC4", "PC3", "PC2", "PC1", "PC0", "PD7", "PG2",
"PG1", "PG0", "PL7", "PL6", "PL5", "PL4", "PL3", "PL2", "PL1", "PL0",
"PB3", "PB2", "PB1", "PB0", "PF0", "PF1", "PF2", "PF3", "PF4", "PF5",
"PF6", "PF7", "PK0", "PK1", "PK2", "PK3", "PK4", "PK5", "PK6", "PK7",
]
Arduino_analog_mega = [
"PF0", "PF1", "PF2", "PF3", "PF4", "PF5",
"PF6", "PF7", "PK0", "PK1", "PK2", "PK3", "PK4", "PK5", "PK6", "PK7",
]
Sanguino = [
"PB0", "PB1", "PB2", "PB3", "PB4", "PB5", "PB6", "PB7", "PD0", "PD1",
"PD2", "PD3", "PD4", "PD5", "PD6", "PD7", "PC0", "PC1", "PC2", "PC3",
"PC4", "PC5", "PC6", "PC7", "PA0", "PA1", "PA2", "PA3", "PA4", "PA5",
"PA6", "PA7"
]
Sanguino_analog = [
"PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", "PA7"
]
Arduino_Due = [
"PA8", "PA9", "PB25", "PC28", "PA29", "PC25", "PC24", "PC23", "PC22", "PC21",
"PA28", "PD7", "PD8", "PB27", "PD4", "PD5", "PA13", "PA12", "PA11", "PA10",
"PB12", "PB13", "PB26", "PA14", "PA15", "PD0", "PD1", "PD2", "PD3", "PD6",
"PD9", "PA7", "PD10", "PC1", "PC2", "PC3", "PC4", "PC5", "PC6", "PC7",
"PC8", "PC9", "PA19", "PA20", "PC19", "PC18", "PC17", "PC16", "PC15", "PC14",
"PC13", "PC12", "PB21", "PB14", "PA16", "PA24", "PA23", "PA22", "PA6", "PA4",
"PA3", "PA2", "PB17", "PB18", "PB19", "PB20", "PB15", "PB16", "PA1", "PA0",
"PA17", "PA18", "PC30", "PA21", "PA25", "PA26", "PA27", "PA28", "PB23"
]
Arduino_Due_analog = [
"PA16", "PA24", "PA23", "PA22", "PA6", "PA4", "PA3", "PA2", "PB17", "PB18",
"PB19", "PB20"
]
Arduino_from_mcu = {
"atmega168": (Arduino_standard, Arduino_analog_standard),
"atmega644p": (Sanguino, Sanguino_analog),
"atmega1280": (Arduino_mega, Arduino_analog_mega),
"atmega2560": (Arduino_mega, Arduino_analog_mega),
"sam3x8e": (Arduino_Due, Arduino_Due_analog),
}
######################################################################
# External commands
######################################################################
# Obtains the pin mappings
def get_pin_map(mcu, mapping_name=None):
pins = MCU_PINS.get(mcu, {})
if mapping_name == 'arduino':
dpins, apins = Arduino_from_mcu.get(mcu, [])
for i in range(len(dpins)):
pins['ar' + str(i)] = pins[dpins[i]]
for i in range(len(apins)):
pins['analog%d' % (i,)] = pins[apins[i]]
return pins
# Translate pin names and tick times in a firmware command
re_pin = re.compile(r'(?P<prefix>[ _]pin=)(?P<name>[^ ]*)')
re_ticks = re.compile(r'TICKS\((?P<ticks>[^)]*)\)')
def update_command(cmd, mcu_freq, pmap):
def pin_fixup(m):
return m.group('prefix') + str(pmap[m.group('name')])
def ticks_fixup(m):
return str(int(mcu_freq * float(m.group('ticks'))))
return re_ticks.sub(ticks_fixup, re_pin.sub(pin_fixup, cmd))

93
klippy/pyhelper.c Normal file
View File

@@ -0,0 +1,93 @@
// Helper functions for C / Python interface
//
// Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
//
// This file may be distributed under the terms of the GNU GPLv3 license.
#include <errno.h> // errno
#include <stdarg.h> // va_start
#include <stdint.h> // uint8_t
#include <stdio.h> // fprintf
#include <string.h> // strerror
#include <time.h> // struct timespec
#include "pyhelper.h" // get_monotonic
// Return the monotonic system time as a double
double
get_monotonic(void)
{
struct timespec ts;
int ret = clock_gettime(CLOCK_MONOTONIC, &ts);
if (ret) {
report_errno("clock_gettime", ret);
return 0.;
}
return (double)ts.tv_sec + (double)ts.tv_nsec * .000000001;
}
// Fill a 'struct timespec' with a system time stored in a double
struct timespec
fill_time(double time)
{
time_t t = time;
return (struct timespec) {t, (time - t)*1000000000. };
}
static void
default_logger(const char *msg)
{
fprintf(stderr, "%s\n", msg);
}
static void (*python_logging_callback)(const char *msg) = default_logger;
void
set_python_logging_callback(void (*func)(const char *))
{
python_logging_callback = func;
}
// Log an error message
void
errorf(const char *fmt, ...)
{
char buf[512];
va_list args;
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
va_end(args);
buf[sizeof(buf)-1] = '\0';
python_logging_callback(buf);
}
// Report 'errno' in a message written to stderr
void
report_errno(char *where, int rc)
{
int e = errno;
errorf("Got error %d in %s: (%d)%s", rc, where, e, strerror(e));
}
// Return a hex character for a given number
#define GETHEX(x) ((x) < 10 ? '0' + (x) : 'e' + (x) - 10)
// Translate a binary string into an ASCII string with escape sequences
char *
dump_string(char *outbuf, int outbuf_size, char *inbuf, int inbuf_size)
{
char *outend = &outbuf[outbuf_size-5], *o = outbuf;
uint8_t *inend = (void*)&inbuf[inbuf_size], *p = (void*)inbuf;
while (p < inend && o < outend) {
uint8_t c = *p++;
if (c > 31 && c < 127 && c != '\\') {
*o++ = c;
continue;
}
*o++ = '\\';
*o++ = 'x';
*o++ = GETHEX(c >> 4);
*o++ = GETHEX(c & 0x0f);
}
*o = '\0';
return outbuf;
}

14
klippy/pyhelper.h Normal file
View File

@@ -0,0 +1,14 @@
#ifndef PYHELPER_H
#define PYHELPER_H
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
double get_monotonic(void);
struct timespec fill_time(double time);
void set_python_logging_callback(void (*func)(const char *));
void errorf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
void report_errno(char *where, int rc);
char *dump_string(char *outbuf, int outbuf_size, char *inbuf, int inbuf_size);
#endif // pyhelper.h

60
klippy/queuelogger.py Normal file
View File

@@ -0,0 +1,60 @@
# Code to implement asynchronous logging from a background thread
#
# Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import logging, logging.handlers, threading, Queue, time
# Class to forward all messages through a queue to a background thread
class QueueHandler(logging.Handler):
def __init__(self, queue):
logging.Handler.__init__(self)
self.queue = queue
def emit(self, record):
try:
self.format(record)
record.msg = record.message
record.args = None
record.exc_info = None
self.queue.put_nowait(record)
except Exception:
self.handleError(record)
# Class to poll a queue in a background thread and log each message
class QueueListener(logging.handlers.TimedRotatingFileHandler):
def __init__(self, filename):
logging.handlers.TimedRotatingFileHandler.__init__(
self, filename, when='midnight', backupCount=5)
self.bg_queue = Queue.Queue()
self.bg_thread = threading.Thread(target=self._bg_thread)
self.bg_thread.start()
self.rollover_info = {}
def _bg_thread(self):
while 1:
record = self.bg_queue.get(True)
if record is None:
break
self.handle(record)
def stop(self):
self.bg_queue.put_nowait(None)
self.bg_thread.join()
def set_rollover_info(self, name, info):
self.rollover_info[name] = info
def doRollover(self):
logging.handlers.TimedRotatingFileHandler.doRollover(self)
lines = [self.rollover_info[name]
for name in sorted(self.rollover_info)
if self.rollover_info[name]]
lines.append(
"=============== Log rollover at %s ===============" % (
time.asctime(),))
self.emit(logging.makeLogRecord(
{'msg': "\n".join(lines), 'level': logging.INFO}))
def setup_bg_logging(filename, debuglevel):
ql = QueueListener(filename)
qh = QueueHandler(ql.bg_queue)
root = logging.getLogger()
root.addHandler(qh)
root.setLevel(debuglevel)
return ql

201
klippy/reactor.py Normal file
View File

@@ -0,0 +1,201 @@
# File descriptor and timer event helper
#
# Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import select, math, time
import greenlet
import chelper
class ReactorTimer:
def __init__(self, callback, waketime):
self.callback = callback
self.waketime = waketime
class ReactorFileHandler:
def __init__(self, fd, callback):
self.fd = fd
self.callback = callback
def fileno(self):
return self.fd
class ReactorGreenlet(greenlet.greenlet):
def __init__(self, run):
greenlet.greenlet.__init__(self, run=run)
self.timer = None
class SelectReactor:
NOW = 0.
NEVER = 9999999999999999.
def __init__(self):
self._fds = []
self._timers = []
self._next_timer = self.NEVER
self._process = False
self._g_dispatch = None
self._greenlets = []
self.monotonic = chelper.get_ffi()[1].get_monotonic
# Timers
def _note_time(self, t):
nexttime = t.waketime
if nexttime < self._next_timer:
self._next_timer = nexttime
def update_timer(self, t, nexttime):
t.waketime = nexttime
self._note_time(t)
def register_timer(self, callback, waketime = NEVER):
handler = ReactorTimer(callback, waketime)
timers = list(self._timers)
timers.append(handler)
self._timers = timers
self._note_time(handler)
return handler
def unregister_timer(self, handler):
timers = list(self._timers)
timers.pop(timers.index(handler))
self._timers = timers
def _check_timers(self, eventtime):
if eventtime < self._next_timer:
return min(1., max(.001, self._next_timer - eventtime))
self._next_timer = self.NEVER
g_dispatch = self._g_dispatch
for t in self._timers:
if eventtime >= t.waketime:
t.waketime = self.NEVER
t.waketime = t.callback(eventtime)
if g_dispatch is not self._g_dispatch:
self._end_greenlet(g_dispatch)
return 0.
self._note_time(t)
if eventtime >= self._next_timer:
return 0.
return min(1., max(.001, self._next_timer - self.monotonic()))
# Greenlets
def _sys_pause(self, waketime):
# Pause using system sleep for when reactor not running
delay = waketime - self.monotonic()
if delay > 0.:
time.sleep(delay)
return self.monotonic()
def pause(self, waketime):
g = greenlet.getcurrent()
if g is not self._g_dispatch:
if self._g_dispatch is None:
return self._sys_pause(waketime)
return self._g_dispatch.switch(waketime)
if self._greenlets:
g_next = self._greenlets.pop()
else:
g_next = ReactorGreenlet(run=self._dispatch_loop)
g_next.parent = g.parent
g.timer = self.register_timer(g.switch, waketime)
return g_next.switch()
def _end_greenlet(self, g_old):
self._greenlets.append(g_old)
self.unregister_timer(g_old.timer)
g_old.timer = None
self._g_dispatch.switch(self.NEVER)
self._g_dispatch = g_old
# File descriptors
def register_fd(self, fd, callback):
handler = ReactorFileHandler(fd, callback)
self._fds.append(handler)
return handler
def unregister_fd(self, handler):
self._fds.pop(self._fds.index(handler))
# Main loop
def _dispatch_loop(self):
self._g_dispatch = g_dispatch = greenlet.getcurrent()
eventtime = self.monotonic()
while self._process:
timeout = self._check_timers(eventtime)
res = select.select(self._fds, [], [], timeout)
eventtime = self.monotonic()
for fd in res[0]:
fd.callback(eventtime)
if g_dispatch is not self._g_dispatch:
self._end_greenlet(g_dispatch)
eventtime = self.monotonic()
break
self._g_dispatch = None
def run(self):
self._process = True
g_next = ReactorGreenlet(run=self._dispatch_loop)
g_next.switch()
def end(self):
self._process = False
class PollReactor(SelectReactor):
def __init__(self):
SelectReactor.__init__(self)
self._poll = select.poll()
self._fds = {}
# File descriptors
def register_fd(self, fd, callback):
handler = ReactorFileHandler(fd, callback)
fds = self._fds.copy()
fds[fd] = callback
self._fds = fds
self._poll.register(handler, select.POLLIN | select.POLLHUP)
return handler
def unregister_fd(self, handler):
self._poll.unregister(handler)
fds = self._fds.copy()
del fds[handler.fd]
self._fds = fds
# Main loop
def _dispatch_loop(self):
self._g_dispatch = g_dispatch = greenlet.getcurrent()
eventtime = self.monotonic()
while self._process:
timeout = self._check_timers(eventtime)
res = self._poll.poll(int(math.ceil(timeout * 1000.)))
eventtime = self.monotonic()
for fd, event in res:
self._fds[fd](eventtime)
if g_dispatch is not self._g_dispatch:
self._end_greenlet(g_dispatch)
eventtime = self.monotonic()
break
self._g_dispatch = None
class EPollReactor(SelectReactor):
def __init__(self):
SelectReactor.__init__(self)
self._epoll = select.epoll()
self._fds = {}
# File descriptors
def register_fd(self, fd, callback):
handler = ReactorFileHandler(fd, callback)
fds = self._fds.copy()
fds[fd] = callback
self._fds = fds
self._epoll.register(fd, select.EPOLLIN | select.EPOLLHUP)
return handler
def unregister_fd(self, handler):
self._epoll.unregister(handler.fd)
fds = self._fds.copy()
del fds[handler.fd]
self._fds = fds
# Main loop
def _dispatch_loop(self):
self._g_dispatch = g_dispatch = greenlet.getcurrent()
eventtime = self.monotonic()
while self._process:
timeout = self._check_timers(eventtime)
res = self._epoll.poll(timeout)
eventtime = self.monotonic()
for fd, event in res:
self._fds[fd](eventtime)
if g_dispatch is not self._g_dispatch:
self._end_greenlet(g_dispatch)
eventtime = self.monotonic()
break
self._g_dispatch = None
# Use the poll based reactor if it is available
try:
select.poll
Reactor = PollReactor
except:
Reactor = SelectReactor

347
klippy/serialhdl.py Normal file
View File

@@ -0,0 +1,347 @@
# Serial port management for firmware communication
#
# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import logging, threading
import serial
import msgproto, chelper, util
class error(Exception):
pass
class SerialReader:
BITS_PER_BYTE = 10.
def __init__(self, reactor, serialport, baud):
self.reactor = reactor
self.serialport = serialport
self.baud = baud
# Serial port
self.ser = None
self.msgparser = msgproto.MessageParser()
# C interface
self.ffi_main, self.ffi_lib = chelper.get_ffi()
self.serialqueue = None
self.default_cmd_queue = self.alloc_command_queue()
self.stats_buf = self.ffi_main.new('char[4096]')
# MCU time/clock tracking
self.last_ack_time = self.last_ack_rtt_time = 0.
self.last_ack_clock = self.last_ack_rtt_clock = 0
self.est_clock = 0.
# Threading
self.lock = threading.Lock()
self.background_thread = None
# Message handlers
self.status_timer = self.reactor.register_timer(self._status_event)
self.status_cmd = None
handlers = {
'#unknown': self.handle_unknown,
'#output': self.handle_output, 'status': self.handle_status,
'shutdown': self.handle_output, 'is_shutdown': self.handle_output
}
self.handlers = dict(((k, None), v) for k, v in handlers.items())
def _bg_thread(self):
response = self.ffi_main.new('struct pull_queue_message *')
while 1:
self.ffi_lib.serialqueue_pull(self.serialqueue, response)
count = response.len
if count <= 0:
break
params = self.msgparser.parse(response.msg[0:count])
params['#sent_time'] = response.sent_time
params['#receive_time'] = response.receive_time
with self.lock:
hdl = (params['#name'], params.get('oid'))
hdl = self.handlers.get(hdl, self.handle_default)
try:
hdl(params)
except:
logging.exception("Exception in serial callback")
def connect(self):
# Initial connection
logging.info("Starting serial connect")
while 1:
starttime = self.reactor.monotonic()
try:
self.ser = serial.Serial(self.serialport, self.baud, timeout=0)
except (OSError, serial.SerialException), e:
logging.warn("Unable to open port: %s" % (e,))
self.reactor.pause(starttime + 5.)
continue
stk500v2_leave(self.ser, self.reactor)
self.serialqueue = self.ffi_lib.serialqueue_alloc(
self.ser.fileno(), 0)
self.background_thread = threading.Thread(target=self._bg_thread)
self.background_thread.start()
# Obtain and load the data dictionary from the firmware
sbs = SerialBootStrap(self)
identify_data = sbs.get_identify_data(starttime + 5.)
if identify_data is None:
logging.warn("Timeout on serial connect")
self.disconnect()
continue
break
msgparser = msgproto.MessageParser()
msgparser.process_identify(identify_data)
self.msgparser = msgparser
self.register_callback(self.handle_unknown, '#unknown')
logging.info("Loaded %d commands (%s)" % (
len(msgparser.messages_by_id), msgparser.version))
logging.info("MCU config: %s" % (" ".join(
["%s=%s" % (k, v) for k, v in msgparser.config.items()])))
# Setup baud adjust
mcu_baud = float(msgparser.config.get('SERIAL_BAUD', 0.))
if mcu_baud:
baud_adjust = self.BITS_PER_BYTE / mcu_baud
self.ffi_lib.serialqueue_set_baud_adjust(
self.serialqueue, baud_adjust)
# Enable periodic get_status timer
get_status = msgparser.lookup_command('get_status')
self.status_cmd = get_status.encode()
self.reactor.update_timer(self.status_timer, self.reactor.NOW)
# Load initial last_ack_clock/last_ack_time
uptime_msg = msgparser.create_command('get_uptime')
params = self.send_with_response(uptime_msg, 'uptime')
self.last_ack_clock = (params['high'] << 32) | params['clock']
self.last_ack_time = params['#receive_time']
# Make sure est_clock is calculated
starttime = eventtime = self.reactor.monotonic()
while not self.est_clock:
if eventtime > starttime + 5.:
raise error("timeout on est_clock calculation")
eventtime = self.reactor.pause(eventtime + 0.010)
def connect_file(self, debugoutput, dictionary, pace=False):
self.ser = debugoutput
self.msgparser.process_identify(dictionary, decompress=False)
est_clock = 1000000000000.
if pace:
est_clock = float(self.msgparser.config['CLOCK_FREQ'])
self.serialqueue = self.ffi_lib.serialqueue_alloc(self.ser.fileno(), 1)
self.est_clock = est_clock
self.last_ack_time = self.reactor.monotonic()
self.last_ack_clock = 0
self.ffi_lib.serialqueue_set_clock_est(
self.serialqueue, self.est_clock, self.last_ack_time
, self.last_ack_clock)
def disconnect(self):
if self.serialqueue is not None:
self.ffi_lib.serialqueue_exit(self.serialqueue)
if self.background_thread is not None:
self.background_thread.join()
self.ffi_lib.serialqueue_free(self.serialqueue)
self.background_thread = self.serialqueue = None
if self.ser is not None:
self.ser.close()
self.ser = None
def stats(self, eventtime):
if self.serialqueue is None:
return ""
sqstats = self.ffi_lib.serialqueue_get_stats(
self.serialqueue, self.stats_buf, len(self.stats_buf))
sqstats = self.ffi_main.string(self.stats_buf)
tstats = " est_clock=%.3f last_ack_time=%.3f last_ack_clock=%d" % (
self.est_clock, self.last_ack_time, self.last_ack_clock)
return sqstats + tstats
def _status_event(self, eventtime):
self.send(self.status_cmd)
return eventtime + 1.0
# Serial response callbacks
def register_callback(self, callback, name, oid=None):
with self.lock:
self.handlers[name, oid] = callback
def unregister_callback(self, name, oid=None):
with self.lock:
del self.handlers[name, oid]
# Clock tracking
def get_clock(self, eventtime):
with self.lock:
return int(self.last_ack_clock
+ (eventtime - self.last_ack_time) * self.est_clock)
def translate_clock(self, raw_clock):
with self.lock:
last_ack_clock = self.last_ack_clock
clock_diff = (last_ack_clock - raw_clock) & 0xffffffff
if clock_diff & 0x80000000:
return last_ack_clock + 0x100000000 - clock_diff
return last_ack_clock - clock_diff
def get_last_clock(self):
with self.lock:
return self.last_ack_clock, self.last_ack_time
# Command sending
def send(self, cmd, minclock=0, reqclock=0, cq=None):
if cq is None:
cq = self.default_cmd_queue
self.ffi_lib.serialqueue_send(
self.serialqueue, cq, cmd, len(cmd), minclock, reqclock)
def encode_and_send(self, data, minclock, reqclock, cq):
self.ffi_lib.serialqueue_encode_and_send(
self.serialqueue, cq, data, len(data), minclock, reqclock)
def send_with_response(self, cmd, name, oid=None):
src = SerialRetryCommand(self, cmd, name, oid)
return src.get_response()
def alloc_command_queue(self):
return self.ffi_main.gc(self.ffi_lib.serialqueue_alloc_commandqueue(),
self.ffi_lib.serialqueue_free_commandqueue)
# Dumping debug lists
def dump_debug(self):
sdata = self.ffi_main.new('struct pull_queue_message[1024]')
rdata = self.ffi_main.new('struct pull_queue_message[1024]')
scount = self.ffi_lib.serialqueue_extract_old(
self.serialqueue, 1, sdata, len(sdata))
rcount = self.ffi_lib.serialqueue_extract_old(
self.serialqueue, 0, rdata, len(rdata))
logging.info("Dumping send queue %d messages" % (scount,))
for i in range(scount):
msg = sdata[i]
cmds = self.msgparser.dump(msg.msg[0:msg.len])
logging.info("Sent %d %f %f %d: %s" % (
i, msg.receive_time, msg.sent_time, msg.len, ', '.join(cmds)))
logging.info("Dumping receive queue %d messages" % (rcount,))
for i in range(rcount):
msg = rdata[i]
cmds = self.msgparser.dump(msg.msg[0:msg.len])
logging.info("Receive: %d %f %f %d: %s" % (
i, msg.receive_time, msg.sent_time, msg.len, ', '.join(cmds)))
# Default message handlers
def handle_status(self, params):
with self.lock:
# Update last_ack_time / last_ack_clock
ack_clock = (self.last_ack_clock & ~0xffffffff) | params['clock']
if ack_clock < self.last_ack_clock:
ack_clock += 0x100000000
sent_time = params['#sent_time']
self.last_ack_time = receive_time = params['#receive_time']
self.last_ack_clock = ack_clock
# Update est_clock (if applicable)
if receive_time > self.last_ack_rtt_time + 1. and sent_time:
if self.last_ack_rtt_time:
timedelta = receive_time - self.last_ack_rtt_time
clockdelta = ack_clock - self.last_ack_rtt_clock
estclock = clockdelta / timedelta
if estclock > self.est_clock and self.est_clock:
self.est_clock = (self.est_clock * 63. + estclock) / 64.
else:
self.est_clock = estclock
self.last_ack_rtt_time = sent_time
self.last_ack_rtt_clock = ack_clock
self.ffi_lib.serialqueue_set_clock_est(
self.serialqueue, self.est_clock, receive_time, ack_clock)
def handle_unknown(self, params):
logging.warn("Unknown message type %d: %s" % (
params['#msgid'], repr(params['#msg'])))
def handle_output(self, params):
logging.info("%s: %s" % (params['#name'], params['#msg']))
def handle_default(self, params):
logging.warn("got %s" % (params,))
def __del__(self):
self.disconnect()
# Class to retry sending of a query command until a given response is received
class SerialRetryCommand:
TIMEOUT_TIME = 5.0
RETRY_TIME = 0.500
def __init__(self, serial, cmd, name, oid=None):
self.serial = serial
self.cmd = cmd
self.name = name
self.oid = oid
self.response = None
self.min_query_time = self.serial.reactor.monotonic()
self.serial.register_callback(self.handle_callback, self.name, self.oid)
self.send_timer = self.serial.reactor.register_timer(
self.send_event, self.serial.reactor.NOW)
def unregister(self):
self.serial.unregister_callback(self.name, self.oid)
self.serial.reactor.unregister_timer(self.send_timer)
def send_event(self, eventtime):
if self.response is not None:
return self.serial.reactor.NEVER
self.serial.send(self.cmd)
return eventtime + self.RETRY_TIME
def handle_callback(self, params):
last_sent_time = params['#sent_time']
if last_sent_time >= self.min_query_time:
self.response = params
def get_response(self):
eventtime = self.serial.reactor.monotonic()
while self.response is None:
eventtime = self.serial.reactor.pause(eventtime + 0.05)
if eventtime > self.min_query_time + self.TIMEOUT_TIME:
self.unregister()
raise error("Timeout on wait for '%s' response" % (self.name,))
self.unregister()
return self.response
# Code to start communication and download message type dictionary
class SerialBootStrap:
RETRY_TIME = 0.500
def __init__(self, serial):
self.serial = serial
self.identify_data = ""
self.identify_cmd = self.serial.msgparser.lookup_command(
"identify offset=%u count=%c")
self.is_done = False
self.serial.register_callback(self.handle_identify, 'identify_response')
self.serial.register_callback(self.handle_unknown, '#unknown')
self.send_timer = self.serial.reactor.register_timer(
self.send_event, self.serial.reactor.NOW)
def get_identify_data(self, timeout):
eventtime = self.serial.reactor.monotonic()
while not self.is_done and eventtime <= timeout:
eventtime = self.serial.reactor.pause(eventtime + 0.05)
self.serial.unregister_callback('identify_response')
self.serial.reactor.unregister_timer(self.send_timer)
if not self.is_done:
return None
return self.identify_data
def handle_identify(self, params):
if self.is_done or params['offset'] != len(self.identify_data):
return
msgdata = params['data']
if not msgdata:
self.is_done = True
return
self.identify_data += msgdata
imsg = self.identify_cmd.encode(len(self.identify_data), 40)
self.serial.send(imsg)
def send_event(self, eventtime):
if self.is_done:
return self.serial.reactor.NEVER
imsg = self.identify_cmd.encode(len(self.identify_data), 40)
self.serial.send(imsg)
return eventtime + self.RETRY_TIME
def handle_unknown(self, params):
logging.debug("Unknown message %d (len %d) while identifying" % (
params['#msgid'], len(params['#msg'])))
# Attempt to place an AVR stk500v2 style programmer into normal mode
def stk500v2_leave(ser, reactor):
logging.debug("Starting stk500v2 leave programmer sequence")
util.clear_hupcl(ser.fileno())
origbaud = ser.baudrate
# Request a dummy speed first as this seems to help reset the port
ser.baudrate = 2400
ser.read(1)
# Send stk500v2 leave programmer sequence
ser.baudrate = 115200
reactor.pause(reactor.monotonic() + 0.100)
ser.read(4096)
ser.write('\x1b\x01\x00\x01\x0e\x11\x04')
reactor.pause(reactor.monotonic() + 0.050)
res = ser.read(4096)
logging.debug("Got %s from stk500v2" % (repr(res),))
ser.baudrate = origbaud
# Attempt an arduino style reset on a serial port
def arduino_reset(serialport, reactor):
# First try opening the port at 1200 baud
ser = serial.Serial(serialport, 1200, timeout=0)
ser.read(1)
reactor.pause(reactor.monotonic() + 0.100)
# Then try toggling DTR
ser.dtr = True
reactor.pause(reactor.monotonic() + 0.100)
ser.dtr = False
reactor.pause(reactor.monotonic() + 0.100)
ser.close()

1045
klippy/serialqueue.c Normal file

File diff suppressed because it is too large Load Diff

68
klippy/serialqueue.h Normal file
View File

@@ -0,0 +1,68 @@
#ifndef SERIALQUEUE_H
#define SERIALQUEUE_H
#include "list.h" // struct list_head
#define MAX_CLOCK 0x7fffffffffffffff
#define MESSAGE_MIN 5
#define MESSAGE_MAX 64
#define MESSAGE_HEADER_SIZE 2
#define MESSAGE_TRAILER_SIZE 3
#define MESSAGE_POS_LEN 0
#define MESSAGE_POS_SEQ 1
#define MESSAGE_TRAILER_CRC 3
#define MESSAGE_TRAILER_SYNC 1
#define MESSAGE_PAYLOAD_MAX (MESSAGE_MAX - MESSAGE_MIN)
#define MESSAGE_SEQ_MASK 0x0f
#define MESSAGE_DEST 0x10
#define MESSAGE_SYNC 0x7E
struct queue_message {
int len;
uint8_t msg[MESSAGE_MAX];
union {
// Filled when on a command queue
struct {
uint64_t min_clock, req_clock;
};
// Filled when in sent/receive queues
struct {
double sent_time, receive_time;
};
};
struct list_node node;
};
struct queue_message *message_alloc_and_encode(uint32_t *data, int len);
void message_queue_free(struct list_head *root);
struct pull_queue_message {
uint8_t msg[MESSAGE_MAX];
int len;
double sent_time, receive_time;
};
struct serialqueue;
struct serialqueue *serialqueue_alloc(int serial_fd, int write_only);
void serialqueue_exit(struct serialqueue *sq);
void serialqueue_free(struct serialqueue *sq);
struct command_queue *serialqueue_alloc_commandqueue(void);
void serialqueue_free_commandqueue(struct command_queue *cq);
void serialqueue_send_batch(struct serialqueue *sq, struct command_queue *cq
, struct list_head *msgs);
void serialqueue_send(struct serialqueue *sq, struct command_queue *cq
, uint8_t *msg, int len
, uint64_t min_clock, uint64_t req_clock);
void serialqueue_encode_and_send(struct serialqueue *sq, struct command_queue *cq
, uint32_t *data, int len
, uint64_t min_clock, uint64_t req_clock);
void serialqueue_pull(struct serialqueue *sq, struct pull_queue_message *pqm);
void serialqueue_set_baud_adjust(struct serialqueue *sq, double baud_adjust);
void serialqueue_set_clock_est(struct serialqueue *sq, double est_clock
, double last_ack_time, uint64_t last_ack_clock);
void serialqueue_get_stats(struct serialqueue *sq, char *buf, int len);
int serialqueue_extract_old(struct serialqueue *sq, int sentq
, struct pull_queue_message *q, int max);
#endif // serialqueue.h

797
klippy/stepcompress.c Normal file
View File

@@ -0,0 +1,797 @@
// Stepper pulse schedule compression
//
// Copyright (C) 2016,2017 Kevin O'Connor <kevin@koconnor.net>
//
// This file may be distributed under the terms of the GNU GPLv3 license.
//
// The goal of this code is to take a series of scheduled stepper
// pulse times and compress them into a handful of commands that can
// be efficiently transmitted and executed on a microcontroller (mcu).
// The mcu accepts step pulse commands that take interval, count, and
// add parameters such that 'count' pulses occur, with each step event
// calculating the next step event time using:
// next_wake_time = last_wake_time + interval; interval += add
// This code is writtin in C (instead of python) for processing
// efficiency - the repetitive integer math is vastly faster in C.
#include <math.h> // sqrt
#include <stddef.h> // offsetof
#include <stdint.h> // uint32_t
#include <stdio.h> // fprintf
#include <stdlib.h> // malloc
#include <string.h> // memset
#include "pyhelper.h" // errorf
#include "serialqueue.h" // struct queue_message
#define CHECK_LINES 1
#define QUEUE_START_SIZE 1024
struct stepcompress {
// Buffer management
uint64_t *queue, *queue_end, *queue_pos, *queue_next;
// Internal tracking
uint32_t max_error;
// Message generation
uint64_t last_step_clock, homing_clock;
struct list_head msg_queue;
uint32_t queue_step_msgid, set_next_step_dir_msgid, oid;
int sdir, invert_sdir;
};
/****************************************************************
* Queue management
****************************************************************/
// Shuffle the internal queue to avoid having to allocate more ram
static void
clean_queue(struct stepcompress *sc)
{
int in_use = sc->queue_next - sc->queue_pos;
memmove(sc->queue, sc->queue_pos, in_use * sizeof(*sc->queue));
sc->queue_pos = sc->queue;
sc->queue_next = sc->queue + in_use;
}
// Expand the internal queue of step times
static void
expand_queue(struct stepcompress *sc, int count)
{
int alloc = sc->queue_end - sc->queue;
if (count + sc->queue_next - sc->queue_pos <= alloc) {
clean_queue(sc);
return;
}
int pos = sc->queue_pos - sc->queue;
int next = sc->queue_next - sc->queue;
if (!alloc)
alloc = QUEUE_START_SIZE;
while (next + count > alloc)
alloc *= 2;
sc->queue = realloc(sc->queue, alloc * sizeof(*sc->queue));
sc->queue_end = sc->queue + alloc;
sc->queue_pos = sc->queue + pos;
sc->queue_next = sc->queue + next;
}
/****************************************************************
* Step compression
****************************************************************/
#define DIV_UP(n,d) (((n) + (d) - 1) / (d))
static inline int32_t
idiv_up(int32_t n, int32_t d)
{
return (n>=0) ? DIV_UP(n,d) : (n/d);
}
static inline int32_t
idiv_down(int32_t n, int32_t d)
{
return (n>=0) ? (n/d) : (n - d + 1) / d;
}
struct points {
int32_t minp, maxp;
};
// Given a requested step time, return the minimum and maximum
// acceptable times
static inline struct points
minmax_point(struct stepcompress *sc, uint64_t *pos)
{
uint32_t prevpoint = pos > sc->queue_pos ? *(pos-1) - sc->last_step_clock : 0;
uint32_t point = *pos - sc->last_step_clock;
uint32_t max_error = (point - prevpoint) / 2;
if (max_error > sc->max_error)
max_error = sc->max_error;
return (struct points){ point - max_error, point };
}
// The maximum add delta between two valid quadratic sequences of the
// form "add*count*(count-1)/2 + interval*count" is "(6 + 4*sqrt(2)) *
// maxerror / (count*count)". The "6 + 4*sqrt(2)" is 11.65685, but
// using 11 works well in practice.
#define QUADRATIC_DEV 11
struct step_move {
uint32_t interval;
uint16_t count;
int16_t add;
};
// Find a 'step_move' that covers a series of step times
static struct step_move
compress_bisect_add(struct stepcompress *sc)
{
struct points point = minmax_point(sc, sc->queue_pos);
int32_t outer_mininterval = point.minp, outer_maxinterval = point.maxp;
int32_t add = 0, minadd = -0x8000, maxadd = 0x7fff;
int32_t bestinterval = 0, bestcount = 1, bestadd = 1, bestreach = INT32_MIN;
int32_t zerointerval = 0, zerocount = 0;
for (;;) {
// Find longest valid sequence with the given 'add'
struct points nextpoint;
int32_t nextmininterval = outer_mininterval;
int32_t nextmaxinterval = outer_maxinterval, interval = nextmaxinterval;
int32_t nextcount = 1;
for (;;) {
nextcount++;
if (nextcount > bestcount
&& (&sc->queue_pos[nextcount-1] >= sc->queue_next
|| sc->queue_pos[nextcount-1] >= sc->last_step_clock+(3<<28)
|| nextcount > 65535)) {
int32_t count = nextcount - 1;
return (struct step_move){ interval, count, add };
}
nextpoint = minmax_point(sc, sc->queue_pos + nextcount - 1);
int32_t nextaddfactor = nextcount*(nextcount-1)/2;
int32_t c = add*nextaddfactor;
if (nextmininterval*nextcount < nextpoint.minp - c)
nextmininterval = DIV_UP(nextpoint.minp - c, nextcount);
if (nextmaxinterval*nextcount > nextpoint.maxp - c)
nextmaxinterval = (nextpoint.maxp - c) / nextcount;
if (nextmininterval > nextmaxinterval)
break;
interval = nextmaxinterval;
}
// Check if this is the best sequence found so far
int32_t count = nextcount - 1, addfactor = count*(count-1)/2;
int32_t reach = add*addfactor + interval*count;
if (reach > bestreach
|| (reach == bestreach && interval > bestinterval)) {
bestinterval = interval;
bestcount = count;
bestadd = add;
bestreach = reach;
if (!add) {
zerointerval = interval;
zerocount = count;
}
if (count > 0x200)
// No 'add' will improve sequence; avoid integer overflow
break;
}
// Check if a greater or lesser add could extend the sequence
int32_t nextaddfactor = nextcount*(nextcount-1)/2;
int32_t nextreach = add*nextaddfactor + interval*nextcount;
if (nextreach < nextpoint.minp) {
minadd = add + 1;
outer_maxinterval = nextmaxinterval;
} else {
maxadd = add - 1;
outer_mininterval = nextmininterval;
}
// The maximum valid deviation between two quadratic sequences
// can be calculated and used to further limit the add range.
if (count > 1) {
int32_t errdelta = sc->max_error*QUADRATIC_DEV / (count*count);
if (minadd < add - errdelta)
minadd = add - errdelta;
if (maxadd > add + errdelta)
maxadd = add + errdelta;
}
// See if next point would further limit the add range
int32_t c = outer_maxinterval * nextcount;
if (minadd*nextaddfactor < nextpoint.minp - c)
minadd = idiv_up(nextpoint.minp - c, nextaddfactor);
c = outer_mininterval * nextcount;
if (maxadd*nextaddfactor > nextpoint.maxp - c)
maxadd = idiv_down(nextpoint.maxp - c, nextaddfactor);
// Bisect valid add range and try again with new 'add'
if (minadd > maxadd)
break;
add = maxadd - (maxadd - minadd) / 4;
}
if (zerocount + zerocount/16 >= bestcount)
// Prefer add=0 if it's similar to the best found sequence
return (struct step_move){ zerointerval, zerocount, 0 };
return (struct step_move){ bestinterval, bestcount, bestadd };
}
/****************************************************************
* Step compress checking
****************************************************************/
#define ERROR_RET -989898989
// Verify that a given 'step_move' matches the actual step times
static int
check_line(struct stepcompress *sc, struct step_move move)
{
if (!CHECK_LINES)
return 0;
if (move.count == 1) {
if (move.interval != (uint32_t)(*sc->queue_pos - sc->last_step_clock)
|| *sc->queue_pos < sc->last_step_clock) {
errorf("stepcompress o=%d i=%d c=%d a=%d:"
" Count 1 point out of range (%lld)"
, sc->oid, move.interval, move.count, move.add
, (long long)(*sc->queue_pos - sc->last_step_clock));
return ERROR_RET;
}
return 0;
}
if (!move.count || (!move.interval && !move.add)
|| move.interval >= 0x80000000) {
errorf("stepcompress o=%d i=%d c=%d a=%d: Invalid sequence"
, sc->oid, move.interval, move.count, move.add);
return ERROR_RET;
}
uint32_t interval = move.interval, p = 0;
uint16_t i;
for (i=0; i<move.count; i++) {
struct points point = minmax_point(sc, sc->queue_pos + i);
p += interval;
if (p < point.minp || p > point.maxp) {
errorf("stepcompress o=%d i=%d c=%d a=%d: Point %d: %d not in %d:%d"
, sc->oid, move.interval, move.count, move.add
, i+1, p, point.minp, point.maxp);
return ERROR_RET;
}
if (interval >= 0x80000000) {
errorf("stepcompress o=%d i=%d c=%d a=%d:"
" Point %d: interval overflow %d"
, sc->oid, move.interval, move.count, move.add
, i+1, interval);
return ERROR_RET;
}
interval += move.add;
}
return 0;
}
/****************************************************************
* Step compress interface
****************************************************************/
// Allocate a new 'stepcompress' object
struct stepcompress *
stepcompress_alloc(uint32_t max_error, uint32_t queue_step_msgid
, uint32_t set_next_step_dir_msgid, uint32_t invert_sdir
, uint32_t oid)
{
struct stepcompress *sc = malloc(sizeof(*sc));
memset(sc, 0, sizeof(*sc));
sc->max_error = max_error;
list_init(&sc->msg_queue);
sc->queue_step_msgid = queue_step_msgid;
sc->set_next_step_dir_msgid = set_next_step_dir_msgid;
sc->oid = oid;
sc->sdir = -1;
sc->invert_sdir = !!invert_sdir;
return sc;
}
// Free memory associated with a 'stepcompress' object
void
stepcompress_free(struct stepcompress *sc)
{
if (!sc)
return;
free(sc->queue);
message_queue_free(&sc->msg_queue);
free(sc);
}
// Convert previously scheduled steps into commands for the mcu
static int
stepcompress_flush(struct stepcompress *sc, uint64_t move_clock)
{
if (sc->queue_pos >= sc->queue_next)
return 0;
while (move_clock > sc->last_step_clock) {
struct step_move move = compress_bisect_add(sc);
int ret = check_line(sc, move);
if (ret)
return ret;
uint32_t msg[5] = {
sc->queue_step_msgid, sc->oid, move.interval, move.count, move.add
};
struct queue_message *qm = message_alloc_and_encode(msg, 5);
qm->min_clock = qm->req_clock = sc->last_step_clock;
if (move.count == 1 && sc->last_step_clock + (1<<27) < *sc->queue_pos) {
// Be careful with 32bit overflow
sc->last_step_clock = qm->req_clock = *sc->queue_pos;
} else {
int32_t addfactor = move.count*(move.count-1)/2;
uint32_t ticks = move.add*addfactor + move.interval*move.count;
sc->last_step_clock += ticks;
}
if (sc->homing_clock)
// When homing, all steps should be sent prior to homing_clock
qm->min_clock = qm->req_clock = sc->homing_clock;
list_add_tail(&qm->node, &sc->msg_queue);
if (sc->queue_pos + move.count >= sc->queue_next) {
sc->queue_pos = sc->queue_next = sc->queue;
break;
}
sc->queue_pos += move.count;
}
return 0;
}
// Send the set_next_step_dir command
static int
set_next_step_dir(struct stepcompress *sc, int sdir)
{
if (sc->sdir == sdir)
return 0;
sc->sdir = sdir;
int ret = stepcompress_flush(sc, UINT64_MAX);
if (ret)
return ret;
uint32_t msg[3] = {
sc->set_next_step_dir_msgid, sc->oid, sdir ^ sc->invert_sdir
};
struct queue_message *qm = message_alloc_and_encode(msg, 3);
qm->req_clock = sc->homing_clock ?: sc->last_step_clock;
list_add_tail(&qm->node, &sc->msg_queue);
return 0;
}
// Check if the internal queue needs to be expanded, and expand if so
static int
_check_push(struct stepcompress *sc)
{
if (sc->queue_next - sc->queue_pos > 65535 + 2000) {
// No point in keeping more than 64K steps in memory
int ret = stepcompress_flush(sc, *(sc->queue_next - 65535));
if (ret)
return ret;
}
expand_queue(sc, 1);
return 0;
}
static inline int
check_push(struct stepcompress *sc, uint64_t **pqnext, uint64_t **pqend
, uint64_t c)
{
if (unlikely(*pqnext >= *pqend)) {
sc->queue_next = *pqnext;
int ret = _check_push(sc);
if (ret)
return ret;
*pqnext = sc->queue_next;
*pqend = sc->queue_end;
}
*(*pqnext)++ = c;
return 0;
}
// Reset the internal state of the stepcompress object
int
stepcompress_reset(struct stepcompress *sc, uint64_t last_step_clock)
{
int ret = stepcompress_flush(sc, UINT64_MAX);
if (ret)
return ret;
sc->last_step_clock = last_step_clock;
sc->sdir = -1;
return 0;
}
// Indicate the stepper is in homing mode (or done homing if zero)
int
stepcompress_set_homing(struct stepcompress *sc, uint64_t homing_clock)
{
int ret = stepcompress_flush(sc, UINT64_MAX);
if (ret)
return ret;
sc->homing_clock = homing_clock;
return 0;
}
// Queue an mcu command to go out in order with stepper commands
int
stepcompress_queue_msg(struct stepcompress *sc, uint32_t *data, int len)
{
int ret = stepcompress_flush(sc, UINT64_MAX);
if (ret)
return ret;
struct queue_message *qm = message_alloc_and_encode(data, len);
qm->req_clock = sc->homing_clock ?: sc->last_step_clock;
list_add_tail(&qm->node, &sc->msg_queue);
return 0;
}
/****************************************************************
* Motion to step conversions
****************************************************************/
// Wrapper around sqrt() to handle small negative numbers
static double
_safe_sqrt(double v)
{
// Due to floating point truncation, it's possible to get a small
// negative number - treat it as zero.
if (v < -0.001)
errorf("safe_sqrt of %.9f", v);
return 0.;
}
static inline double safe_sqrt(double v) {
return likely(v >= 0.) ? sqrt(v) : _safe_sqrt(v);
}
// Schedule a step event at the specified step_clock time
int
stepcompress_push(struct stepcompress *sc, double step_clock, int32_t sdir)
{
int ret = set_next_step_dir(sc, !!sdir);
if (ret)
return ret;
step_clock += 0.5;
uint64_t *qnext = sc->queue_next, *qend = sc->queue_end;
ret = check_push(sc, &qnext, &qend, step_clock);
if (ret)
return ret;
sc->queue_next = qnext;
return 0;
}
// Common suffixes: _sd is step distance (a unit length the same
// distance the stepper moves on each step), _sv is step velocity (in
// units of step distance per clock tick), _sd2 is step distance
// squared, _r is ratio (scalar usually between 0.0 and 1.0). Times
// are represented as clock ticks (a unit of time determined by a
// micro-controller tick) and acceleration is in units of step
// distance per clock ticks squared.
// Schedule 'steps' number of steps at constant acceleration. If
// acceleration is zero (ie, constant velocity) it uses the formula:
// step_clock = clock_offset + step_num/start_sv
// Otherwise it uses the formula:
// step_clock = (clock_offset + sqrt(2*step_num/accel + (start_sv/accel)**2)
// - start_sv/accel)
int32_t
stepcompress_push_const(
struct stepcompress *sc, double clock_offset
, double step_offset, double steps, double start_sv, double accel)
{
// Calculate number of steps to take
int sdir = 1;
if (steps < 0) {
sdir = 0;
steps = -steps;
step_offset = -step_offset;
}
int count = steps + .5 - step_offset;
if (count <= 0 || count > 10000000) {
if (count && steps) {
errorf("push_const invalid count %d %f %f %f %f %f"
, sc->oid, clock_offset, step_offset, steps
, start_sv, accel);
return ERROR_RET;
}
return 0;
}
int ret = set_next_step_dir(sc, sdir);
if (ret)
return ret;
int res = sdir ? count : -count;
// Calculate each step time
clock_offset += 0.5;
double pos = step_offset + .5;
uint64_t *qnext = sc->queue_next, *qend = sc->queue_end;
if (!accel) {
// Move at constant velocity (zero acceleration)
double inv_cruise_sv = 1. / start_sv;
while (count--) {
uint64_t c = clock_offset + pos*inv_cruise_sv;
int ret = check_push(sc, &qnext, &qend, c);
if (ret)
return ret;
pos += 1.0;
}
} else {
// Move with constant acceleration
double inv_accel = 1. / accel;
clock_offset -= start_sv * inv_accel;
pos += .5 * start_sv*start_sv * inv_accel;
double accel_multiplier = 2. * inv_accel;
while (count--) {
double v = safe_sqrt(pos * accel_multiplier);
uint64_t c = clock_offset + (accel_multiplier >= 0. ? v : -v);
int ret = check_push(sc, &qnext, &qend, c);
if (ret)
return ret;
pos += 1.0;
}
}
sc->queue_next = qnext;
return res;
}
// Schedule steps using delta kinematics
static int32_t
_stepcompress_push_delta(
struct stepcompress *sc, int sdir
, double clock_offset, double move_sd, double start_sv, double accel
, double height, double startxy_sd, double arm_sd, double movez_r)
{
// Calculate number of steps to take
double movexy_r = movez_r ? sqrt(1. - movez_r*movez_r) : 1.;
double arm_sd2 = arm_sd * arm_sd;
double endxy_sd = startxy_sd - movexy_r*move_sd;
double end_height = safe_sqrt(arm_sd2 - endxy_sd*endxy_sd);
int count = (end_height + movez_r*move_sd - height) * (sdir ? 1. : -1.) + .5;
if (count <= 0 || count > 10000000) {
if (count) {
errorf("push_delta invalid count %d %d %f %f %f %f %f %f %f %f"
, sc->oid, count, clock_offset, move_sd, start_sv, accel
, height, startxy_sd, arm_sd, movez_r);
return ERROR_RET;
}
return 0;
}
int ret = set_next_step_dir(sc, sdir);
if (ret)
return ret;
int res = sdir ? count : -count;
// Calculate each step time
clock_offset += 0.5;
height += (sdir ? .5 : -.5);
uint64_t *qnext = sc->queue_next, *qend = sc->queue_end;
if (!accel) {
// Move at constant velocity (zero acceleration)
double inv_cruise_sv = 1. / start_sv;
if (!movez_r) {
// Optimized case for common XY only moves (no Z movement)
while (count--) {
double v = safe_sqrt(arm_sd2 - height*height);
double pos = startxy_sd + (sdir ? -v : v);
uint64_t c = clock_offset + pos * inv_cruise_sv;
int ret = check_push(sc, &qnext, &qend, c);
if (ret)
return ret;
height += (sdir ? 1. : -1.);
}
} else if (!movexy_r) {
// Optimized case for Z only moves
double pos = (sdir ? height-end_height : end_height-height);
while (count--) {
uint64_t c = clock_offset + pos * inv_cruise_sv;
int ret = check_push(sc, &qnext, &qend, c);
if (ret)
return ret;
pos += 1.;
}
} else {
// General case (handles XY+Z moves)
double start_pos = movexy_r*startxy_sd, zoffset = movez_r*startxy_sd;
while (count--) {
double relheight = movexy_r*height - zoffset;
double v = safe_sqrt(arm_sd2 - relheight*relheight);
double pos = start_pos + movez_r*height + (sdir ? -v : v);
uint64_t c = clock_offset + pos * inv_cruise_sv;
int ret = check_push(sc, &qnext, &qend, c);
if (ret)
return ret;
height += (sdir ? 1. : -1.);
}
}
} else {
// Move with constant acceleration
double start_pos = movexy_r*startxy_sd, zoffset = movez_r*startxy_sd;
double inv_accel = 1. / accel;
clock_offset -= start_sv * inv_accel;
start_pos += 0.5 * start_sv*start_sv * inv_accel;
double accel_multiplier = 2. * inv_accel;
while (count--) {
double relheight = movexy_r*height - zoffset;
double v = safe_sqrt(arm_sd2 - relheight*relheight);
double pos = start_pos + movez_r*height + (sdir ? -v : v);
v = safe_sqrt(pos * accel_multiplier);
uint64_t c = clock_offset + (accel_multiplier >= 0. ? v : -v);
int ret = check_push(sc, &qnext, &qend, c);
if (ret)
return ret;
height += (sdir ? 1. : -1.);
}
}
sc->queue_next = qnext;
return res;
}
int32_t
stepcompress_push_delta(
struct stepcompress *sc, double clock_offset, double move_sd
, double start_sv, double accel
, double height, double startxy_sd, double arm_sd, double movez_r)
{
double reversexy_sd = startxy_sd + arm_sd*movez_r;
if (reversexy_sd <= 0.)
// All steps are in down direction
return _stepcompress_push_delta(
sc, 0, clock_offset, move_sd, start_sv, accel
, height, startxy_sd, arm_sd, movez_r);
double movexy_r = movez_r ? sqrt(1. - movez_r*movez_r) : 1.;
if (reversexy_sd >= move_sd * movexy_r)
// All steps are in up direction
return _stepcompress_push_delta(
sc, 1, clock_offset, move_sd, start_sv, accel
, height, startxy_sd, arm_sd, movez_r);
// Steps in both up and down direction
int res1 = _stepcompress_push_delta(
sc, 1, clock_offset, reversexy_sd / movexy_r, start_sv, accel
, height, startxy_sd, arm_sd, movez_r);
if (res1 == ERROR_RET)
return res1;
int res2 = _stepcompress_push_delta(
sc, 0, clock_offset, move_sd, start_sv, accel
, height + res1, startxy_sd, arm_sd, movez_r);
if (res2 == ERROR_RET)
return res2;
return res1 + res2;
}
/****************************************************************
* Step compress synchronization
****************************************************************/
// The steppersync object is used to synchronize the output of mcu
// step commands. The mcu can only queue a limited number of step
// commands - this code tracks when items on the mcu step queue become
// free so that new commands can be transmitted. It also ensures the
// mcu step queue is ordered between steppers so that no stepper
// starves the other steppers of space in the mcu step queue.
struct steppersync {
// Serial port
struct serialqueue *sq;
struct command_queue *cq;
// Storage for associated stepcompress objects
struct stepcompress **sc_list;
int sc_num;
// Storage for list of pending move clocks
uint64_t *move_clocks;
int num_move_clocks;
};
// Allocate a new 'steppersync' object
struct steppersync *
steppersync_alloc(struct serialqueue *sq, struct stepcompress **sc_list
, int sc_num, int move_num)
{
struct steppersync *ss = malloc(sizeof(*ss));
memset(ss, 0, sizeof(*ss));
ss->sq = sq;
ss->cq = serialqueue_alloc_commandqueue();
ss->sc_list = malloc(sizeof(*sc_list)*sc_num);
memcpy(ss->sc_list, sc_list, sizeof(*sc_list)*sc_num);
ss->sc_num = sc_num;
ss->move_clocks = malloc(sizeof(*ss->move_clocks)*move_num);
memset(ss->move_clocks, 0, sizeof(*ss->move_clocks)*move_num);
ss->num_move_clocks = move_num;
return ss;
}
// Free memory associated with a 'steppersync' object
void
steppersync_free(struct steppersync *ss)
{
if (!ss)
return;
free(ss->sc_list);
free(ss->move_clocks);
serialqueue_free_commandqueue(ss->cq);
free(ss);
}
// Implement a binary heap algorithm to track when the next available
// 'struct move' in the mcu will be available
static void
heap_replace(struct steppersync *ss, uint64_t req_clock)
{
uint64_t *mc = ss->move_clocks;
int nmc = ss->num_move_clocks, pos = 0;
for (;;) {
int child1_pos = 2*pos+1, child2_pos = 2*pos+2;
uint64_t child2_clock = child2_pos < nmc ? mc[child2_pos] : UINT64_MAX;
uint64_t child1_clock = child1_pos < nmc ? mc[child1_pos] : UINT64_MAX;
if (req_clock <= child1_clock && req_clock <= child2_clock) {
mc[pos] = req_clock;
break;
}
if (child1_clock < child2_clock) {
mc[pos] = child1_clock;
pos = child1_pos;
} else {
mc[pos] = child2_clock;
pos = child2_pos;
}
}
}
// Find and transmit any scheduled steps prior to the given 'move_clock'
int
steppersync_flush(struct steppersync *ss, uint64_t move_clock)
{
// Flush each stepcompress to the specified move_clock
int i;
for (i=0; i<ss->sc_num; i++) {
int ret = stepcompress_flush(ss->sc_list[i], move_clock);
if (ret)
return ret;
}
// Order commands by the reqclock of each pending command
struct list_head msgs;
list_init(&msgs);
for (;;) {
// Find message with lowest reqclock
uint64_t req_clock = MAX_CLOCK;
struct queue_message *qm = NULL;
for (i=0; i<ss->sc_num; i++) {
struct stepcompress *sc = ss->sc_list[i];
if (!list_empty(&sc->msg_queue)) {
struct queue_message *m = list_first_entry(
&sc->msg_queue, struct queue_message, node);
if (m->req_clock < req_clock) {
qm = m;
req_clock = m->req_clock;
}
}
}
if (!qm || (qm->min_clock && req_clock > move_clock))
break;
uint64_t next_avail = ss->move_clocks[0];
if (qm->min_clock)
// The qm->min_clock field is overloaded to indicate that
// the command uses the 'move queue' and to store the time
// that move queue item becomes available.
heap_replace(ss, qm->min_clock);
// Reset the min_clock to its normal meaning (minimum transmit time)
qm->min_clock = next_avail;
// Batch this command
list_del(&qm->node);
list_add_tail(&qm->node, &msgs);
}
// Transmit commands
if (!list_empty(&msgs))
serialqueue_send_batch(ss->sq, ss->cq, &msgs);
return 0;
}

108
klippy/stepper.py Normal file
View File

@@ -0,0 +1,108 @@
# Printer stepper support
#
# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import math, logging
import homing
class PrinterStepper:
def __init__(self, printer, config, name):
self.name = name
self.step_dist = config.getfloat('step_distance', above=0.)
self.inv_step_dist = 1. / self.step_dist
self.min_stop_interval = 0.
self.homing_speed = config.getfloat('homing_speed', 5.0, above=0.)
self.homing_positive_dir = config.getboolean(
'homing_positive_dir', False)
self.homing_retract_dist = config.getfloat(
'homing_retract_dist', 5., above=0.)
self.homing_stepper_phases = config.getint(
'homing_stepper_phases', None, minval=0)
endstop_accuracy = config.getfloat(
'homing_endstop_accuracy', None, above=0.)
self.homing_endstop_accuracy = self.homing_endstop_phase = None
if self.homing_stepper_phases:
self.homing_endstop_phase = config.getint(
'homing_endstop_phase', None, minval=0
, maxval=self.homing_stepper_phases-1)
if endstop_accuracy is None:
self.homing_endstop_accuracy = self.homing_stepper_phases//2 - 1
elif self.homing_endstop_phase is not None:
self.homing_endstop_accuracy = int(math.ceil(
endstop_accuracy * self.inv_step_dist / 2.))
else:
self.homing_endstop_accuracy = int(math.ceil(
endstop_accuracy * self.inv_step_dist))
if self.homing_endstop_accuracy >= self.homing_stepper_phases/2:
logging.info("Endstop for %s is not accurate enough for stepper"
" phase adjustment" % (name,))
self.homing_stepper_phases = None
if printer.mcu.is_fileoutput():
self.homing_endstop_accuracy = self.homing_stepper_phases
self.position_min = self.position_endstop = self.position_max = None
endstop_pin = config.get('endstop_pin', None)
step_pin = config.get('step_pin')
dir_pin = config.get('dir_pin')
mcu = printer.mcu
self.mcu_stepper = mcu.create_stepper(step_pin, dir_pin)
self.mcu_stepper.set_step_distance(self.step_dist)
enable_pin = config.get('enable_pin', None)
if enable_pin is not None:
self.mcu_enable = mcu.create_digital_out(enable_pin, 0)
if endstop_pin is not None:
self.mcu_endstop = mcu.create_endstop(endstop_pin)
self.mcu_endstop.add_stepper(self.mcu_stepper)
self.position_min = config.getfloat('position_min', 0.)
self.position_max = config.getfloat(
'position_max', 0., above=self.position_min)
self.position_endstop = config.getfloat('position_endstop')
self.need_motor_enable = True
def _dist_to_time(self, dist, start_velocity, accel):
# Calculate the time it takes to travel a distance with constant accel
time_offset = start_velocity / accel
return math.sqrt(2. * dist / accel + time_offset**2) - time_offset
def set_max_jerk(self, max_halt_velocity, max_accel):
# Calculate the firmware's maximum halt interval time
last_step_time = self._dist_to_time(
self.step_dist, max_halt_velocity, max_accel)
second_last_step_time = self._dist_to_time(
2. * self.step_dist, max_halt_velocity, max_accel)
min_stop_interval = second_last_step_time - last_step_time
self.mcu_stepper.set_min_stop_interval(min_stop_interval)
def motor_enable(self, move_time, enable=0):
if enable and self.need_motor_enable:
mcu_time = self.mcu_stepper.print_to_mcu_time(move_time)
self.mcu_stepper.reset_step_clock(mcu_time)
if (self.mcu_enable is not None
and self.mcu_enable.get_last_setting() != enable):
mcu_time = self.mcu_enable.print_to_mcu_time(move_time)
self.mcu_enable.set_digital(mcu_time, enable)
self.need_motor_enable = not enable
def enable_endstop_checking(self, move_time, step_time):
mcu_time = self.mcu_endstop.print_to_mcu_time(move_time)
self.mcu_endstop.home_start(mcu_time, step_time)
return self.mcu_endstop
def query_endstop(self, print_time):
mcu_time = self.mcu_endstop.print_to_mcu_time(print_time)
self.mcu_endstop.query_endstop(mcu_time)
return self.mcu_endstop
def get_homed_offset(self):
if not self.homing_stepper_phases or self.need_motor_enable:
return 0
pos = self.mcu_stepper.get_mcu_position()
pos %= self.homing_stepper_phases
if self.homing_endstop_phase is None:
logging.info("Setting %s endstop phase to %d" % (self.name, pos))
self.homing_endstop_phase = pos
return 0
delta = (pos - self.homing_endstop_phase) % self.homing_stepper_phases
if delta >= self.homing_stepper_phases - self.homing_endstop_accuracy:
delta -= self.homing_stepper_phases
elif delta > self.homing_endstop_accuracy:
raise homing.EndstopError(
"Endstop %s incorrect phase (got %d vs %d)" % (
self.name, pos, self.homing_endstop_phase))
return delta * self.step_dist

384
klippy/toolhead.py Normal file
View File

@@ -0,0 +1,384 @@
# Code for coordinating events on the printer toolhead
#
# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import math, logging
import cartesian, corexy, delta, extruder
# Common suffixes: _d is distance (in mm), _v is velocity (in
# mm/second), _v2 is velocity squared (mm^2/s^2), _t is time (in
# seconds), _r is ratio (scalar between 0.0 and 1.0)
# Class to track each move request
class Move:
def __init__(self, toolhead, start_pos, end_pos, speed):
self.toolhead = toolhead
self.start_pos = tuple(start_pos)
self.end_pos = tuple(end_pos)
self.accel = toolhead.max_accel
self.is_kinematic_move = True
self.axes_d = axes_d = [end_pos[i] - start_pos[i] for i in (0, 1, 2, 3)]
self.move_d = move_d = math.sqrt(sum([d*d for d in axes_d[:3]]))
if not move_d:
# Extrude only move
self.move_d = move_d = abs(axes_d[3])
self.is_kinematic_move = False
self.min_move_t = move_d / speed
# Junction speeds are tracked in velocity squared. The
# delta_v2 is the maximum amount of this squared-velocity that
# can change in this move.
self.max_start_v2 = 0.
self.max_cruise_v2 = speed**2
self.delta_v2 = 2.0 * move_d * self.accel
self.max_smoothed_v2 = 0.
self.smooth_delta_v2 = 2.0 * move_d * toolhead.max_accel_to_decel
def limit_speed(self, speed, accel):
speed2 = speed**2
if speed2 < self.max_cruise_v2:
self.max_cruise_v2 = speed2
self.min_move_t = self.move_d / speed
self.accel = min(self.accel, accel)
self.delta_v2 = 2.0 * self.move_d * self.accel
self.smooth_delta_v2 = min(self.smooth_delta_v2, self.delta_v2)
def calc_junction(self, prev_move):
axes_d = self.axes_d
prev_axes_d = prev_move.axes_d
if (axes_d[2] or prev_axes_d[2] or self.accel != prev_move.accel
or not self.is_kinematic_move or not prev_move.is_kinematic_move):
return
# Allow extruder to calculate its maximum junction
extruder_v2 = self.toolhead.extruder.calc_junction(prev_move, self)
# Find max velocity using approximated centripetal velocity as
# described at:
# https://onehossshay.wordpress.com/2011/09/24/improving_grbl_cornering_algorithm/
junction_cos_theta = -((axes_d[0] * prev_axes_d[0]
+ axes_d[1] * prev_axes_d[1])
/ (self.move_d * prev_move.move_d))
if junction_cos_theta > 0.999999:
return
junction_cos_theta = max(junction_cos_theta, -0.999999)
sin_theta_d2 = math.sqrt(0.5*(1.0-junction_cos_theta))
R = self.toolhead.junction_deviation * sin_theta_d2 / (1. - sin_theta_d2)
self.max_start_v2 = min(
R * self.accel, self.max_cruise_v2, prev_move.max_cruise_v2
, extruder_v2, prev_move.max_start_v2 + prev_move.delta_v2)
self.max_smoothed_v2 = min(
self.max_start_v2
, prev_move.max_smoothed_v2 + prev_move.smooth_delta_v2)
def set_junction(self, start_v2, cruise_v2, end_v2):
# Determine accel, cruise, and decel portions of the move distance
inv_delta_v2 = 1. / self.delta_v2
self.accel_r = accel_r = (cruise_v2 - start_v2) * inv_delta_v2
self.decel_r = decel_r = (cruise_v2 - end_v2) * inv_delta_v2
self.cruise_r = cruise_r = 1. - accel_r - decel_r
# Determine move velocities
self.start_v = start_v = math.sqrt(start_v2)
self.cruise_v = cruise_v = math.sqrt(cruise_v2)
self.end_v = end_v = math.sqrt(end_v2)
# Determine time spent in each portion of move (time is the
# distance divided by average velocity)
self.accel_t = accel_r * self.move_d / ((start_v + cruise_v) * 0.5)
self.cruise_t = cruise_r * self.move_d / cruise_v
self.decel_t = decel_r * self.move_d / ((end_v + cruise_v) * 0.5)
def move(self):
# Generate step times for the move
next_move_time = self.toolhead.get_next_move_time()
if self.is_kinematic_move:
self.toolhead.kin.move(next_move_time, self)
if self.axes_d[3]:
self.toolhead.extruder.move(next_move_time, self)
self.toolhead.update_move_time(
self.accel_t + self.cruise_t + self.decel_t)
LOOKAHEAD_FLUSH_TIME = 0.250
# Class to track a list of pending move requests and to facilitate
# "look-ahead" across moves to reduce acceleration between moves.
class MoveQueue:
def __init__(self, extruder_lookahead):
self.extruder_lookahead = extruder_lookahead
self.queue = []
self.leftover = 0
self.junction_flush = LOOKAHEAD_FLUSH_TIME
def reset(self):
del self.queue[:]
self.leftover = 0
self.junction_flush = LOOKAHEAD_FLUSH_TIME
def set_flush_time(self, flush_time):
self.junction_flush = flush_time
def flush(self, lazy=False):
self.junction_flush = LOOKAHEAD_FLUSH_TIME
update_flush_count = lazy
queue = self.queue
flush_count = len(queue)
# Traverse queue from last to first move and determine maximum
# junction speed assuming the robot comes to a complete stop
# after the last move.
delayed = []
next_end_v2 = next_smoothed_v2 = peak_cruise_v2 = 0.
for i in range(flush_count-1, self.leftover-1, -1):
move = queue[i]
reachable_start_v2 = next_end_v2 + move.delta_v2
start_v2 = min(move.max_start_v2, reachable_start_v2)
reachable_smoothed_v2 = next_smoothed_v2 + move.smooth_delta_v2
smoothed_v2 = min(move.max_smoothed_v2, reachable_smoothed_v2)
if smoothed_v2 < reachable_smoothed_v2:
# It's possible for this move to accelerate
if (smoothed_v2 + move.smooth_delta_v2 > next_smoothed_v2
or delayed):
# This move can decelerate or this is a full accel
# move after a full decel move
if update_flush_count and peak_cruise_v2:
flush_count = i
update_flush_count = False
peak_cruise_v2 = min(move.max_cruise_v2, (
smoothed_v2 + reachable_smoothed_v2) * .5)
if delayed:
# Propagate peak_cruise_v2 to any delayed moves
if not update_flush_count and i < flush_count:
for m, ms_v2, me_v2 in delayed:
mc_v2 = min(peak_cruise_v2, ms_v2)
m.set_junction(min(ms_v2, mc_v2), mc_v2
, min(me_v2, mc_v2))
del delayed[:]
if not update_flush_count and i < flush_count:
cruise_v2 = min((start_v2 + reachable_start_v2) * .5
, move.max_cruise_v2, peak_cruise_v2)
move.set_junction(min(start_v2, cruise_v2), cruise_v2
, min(next_end_v2, cruise_v2))
else:
# Delay calculating this move until peak_cruise_v2 is known
delayed.append((move, start_v2, next_end_v2))
next_end_v2 = start_v2
next_smoothed_v2 = smoothed_v2
if update_flush_count:
return
# Allow extruder to do its lookahead
move_count = self.extruder_lookahead(queue, flush_count, lazy)
# Generate step times for all moves ready to be flushed
for move in queue[:move_count]:
move.move()
# Remove processed moves from the queue
self.leftover = flush_count - move_count
del queue[:move_count]
def add_move(self, move):
self.queue.append(move)
if len(self.queue) == 1:
return
move.calc_junction(self.queue[-2])
self.junction_flush -= move.min_move_t
if self.junction_flush <= 0.:
# There are enough queued moves to return to zero velocity
# from the first move's maximum possible velocity, so at
# least one move can be flushed.
self.flush(lazy=True)
STALL_TIME = 0.100
# Main code to track events (and their timing) on the printer toolhead
class ToolHead:
def __init__(self, printer, config):
self.printer = printer
self.reactor = printer.reactor
self.extruder = printer.objects.get('extruder')
if self.extruder is None:
self.extruder = extruder.DummyExtruder()
kintypes = {'cartesian': cartesian.CartKinematics,
'corexy': corexy.CoreXYKinematics,
'delta': delta.DeltaKinematics}
self.kin = config.getchoice('kinematics', kintypes)(printer, config)
self.max_speed = config.getfloat('max_velocity', above=0.)
self.max_accel = config.getfloat('max_accel', above=0.)
self.max_accel_to_decel = config.getfloat(
'max_accel_to_decel', self.max_accel * 0.5
, above=0., maxval=self.max_accel)
self.junction_deviation = config.getfloat(
'junction_deviation', 0.02, above=0.)
self.move_queue = MoveQueue(self.extruder.lookahead)
self.commanded_pos = [0., 0., 0., 0.]
# Print time tracking
self.buffer_time_low = config.getfloat(
'buffer_time_low', 1.000, above=0.)
self.buffer_time_high = config.getfloat(
'buffer_time_high', 2.000, above=self.buffer_time_low)
self.buffer_time_start = config.getfloat(
'buffer_time_start', 0.250, above=0.)
self.move_flush_time = config.getfloat(
'move_flush_time', 0.050, above=0.)
self.print_time = 0.
self.last_print_end_time = self.reactor.monotonic()
self.need_check_stall = -1.
self.print_stall = 0
self.synch_print_time = True
self.forced_synch = False
self.flush_timer = self.reactor.register_timer(self._flush_handler)
self.move_queue.set_flush_time(self.buffer_time_high)
# Motor off tracking
self.motor_off_time = config.getfloat(
'motor_off_time', 600.000, minval=0.)
self.motor_off_timer = self.reactor.register_timer(
self._motor_off_handler)
# Determine the maximum velocity a cartesian axis could have
# before cornering. The 8. was determined experimentally.
xy_halt = math.sqrt(8. * self.junction_deviation * self.max_accel)
self.kin.set_max_jerk(xy_halt, self.max_speed, self.max_accel)
self.extruder.set_max_jerk(xy_halt, self.max_speed, self.max_accel)
# Print time tracking
def update_move_time(self, movetime):
self.print_time += movetime
flush_to_time = self.print_time - self.move_flush_time
self.printer.mcu.flush_moves(flush_to_time)
def get_next_move_time(self):
if self.synch_print_time:
curtime = self.reactor.monotonic()
if self.print_time:
buffer_time = self.printer.mcu.get_print_buffer_time(
curtime, self.print_time)
self.print_time += max(self.buffer_time_start - buffer_time, 0.)
if self.forced_synch:
self.print_stall += 1
self.forced_synch = False
else:
self.printer.mcu.set_print_start_time(curtime)
self.print_time = self.buffer_time_start
self._reset_motor_off()
self.reactor.update_timer(self.flush_timer, self.reactor.NOW)
self.synch_print_time = False
return self.print_time
def _flush_lookahead(self, must_synch=False):
synch_print_time = self.synch_print_time
self.move_queue.flush()
if synch_print_time or must_synch:
self.synch_print_time = True
self.move_queue.set_flush_time(self.buffer_time_high)
self.printer.mcu.flush_moves(self.print_time)
def get_last_move_time(self):
self._flush_lookahead()
return self.get_next_move_time()
def reset_print_time(self):
self._flush_lookahead(must_synch=True)
self.print_time = 0.
self.last_print_end_time = self.reactor.monotonic()
self.need_check_stall = -1.
self.forced_synch = False
self._reset_motor_off()
def _check_stall(self):
eventtime = self.reactor.monotonic()
if not self.print_time:
# Building initial queue - make sure to flush on idle input
self.reactor.update_timer(self.flush_timer, eventtime + 0.100)
return
# Check if there are lots of queued moves and stall if so
while 1:
buffer_time = self.printer.mcu.get_print_buffer_time(
eventtime, self.print_time)
stall_time = buffer_time - self.buffer_time_high
if stall_time <= 0.:
break
eventtime = self.reactor.pause(eventtime + stall_time)
if not self.print_time:
return
self.need_check_stall = self.print_time - stall_time + 0.100
def _flush_handler(self, eventtime):
try:
if not self.print_time:
# Input idled before filling lookahead queue - flush it
self._flush_lookahead()
if not self.print_time:
return self.reactor.NEVER
print_time = self.print_time
buffer_time = self.printer.mcu.get_print_buffer_time(
eventtime, print_time)
if buffer_time > self.buffer_time_low:
# Running normally - reschedule check
return eventtime + buffer_time - self.buffer_time_low
# Under ran low buffer mark - flush lookahead queue
self._flush_lookahead(must_synch=True)
if print_time != self.print_time:
# Flushed something - retry
self.forced_synch = True
return self.reactor.NOW
if buffer_time > 0.:
# Wait for buffer to fully empty
return eventtime + buffer_time
self.reset_print_time()
except:
logging.exception("Exception in flush_handler")
self.force_shutdown()
return self.reactor.NEVER
# Motor off timer
def _reset_motor_off(self):
if not self.print_time:
waketime = self.reactor.monotonic() + self.motor_off_time
else:
waketime = self.reactor.NEVER
self.reactor.update_timer(self.motor_off_timer, waketime)
def _motor_off_handler(self, eventtime):
try:
self.motor_off()
self.reset_print_time()
except:
logging.exception("Exception in motor_off_handler")
self.force_shutdown()
return self.reactor.NEVER
# Movement commands
def get_position(self):
return list(self.commanded_pos)
def set_position(self, newpos):
self._flush_lookahead()
self.commanded_pos[:] = newpos
self.kin.set_position(newpos)
def move(self, newpos, speed):
speed = min(speed, self.max_speed)
move = Move(self, self.commanded_pos, newpos, speed)
if not move.move_d:
return
if move.is_kinematic_move:
self.kin.check_move(move)
if move.axes_d[3]:
self.extruder.check_move(move)
self.commanded_pos[:] = newpos
self.move_queue.add_move(move)
if self.print_time > self.need_check_stall:
self._check_stall()
def home(self, homing_state):
self.kin.home(homing_state)
def dwell(self, delay):
self.get_last_move_time()
self.update_move_time(delay)
self._check_stall()
def motor_off(self):
self.dwell(STALL_TIME)
last_move_time = self.get_last_move_time()
self.kin.motor_off(last_move_time)
self.extruder.motor_off(last_move_time)
self.dwell(STALL_TIME)
logging.debug('; Max time of %f' % (last_move_time,))
def wait_moves(self):
self._flush_lookahead()
eventtime = self.reactor.monotonic()
while self.print_time:
eventtime = self.reactor.pause(eventtime + 0.100)
def query_endstops(self):
last_move_time = self.get_last_move_time()
return self.kin.query_endstops(last_move_time)
# Misc commands
def stats(self, eventtime):
buffer_time = 0.
print_time = self.print_time
if print_time:
is_active = True
buffer_time = max(0., self.printer.mcu.get_print_buffer_time(
eventtime, print_time))
else:
is_active = eventtime < self.last_print_end_time + 60.
return is_active, "print_time=%.3f buffer_time=%.3f print_stall=%d" % (
print_time, buffer_time, self.print_stall)
def force_shutdown(self):
try:
self.printer.mcu.force_shutdown()
self.move_queue.reset()
self.reset_print_time()
except:
logging.exception("Exception in force_shutdown")

69
klippy/util.py Normal file
View File

@@ -0,0 +1,69 @@
# Low level unix utility functions
#
# Copyright (C) 2016 Kevin O'Connor <kevin@koconnor.net>
#
# This file may be distributed under the terms of the GNU GPLv3 license.
import sys, os, pty, fcntl, termios, signal, logging
import subprocess, traceback, shlex
# Return the SIGINT interrupt handler back to the OS default
def fix_sigint():
signal.signal(signal.SIGINT, signal.SIG_DFL)
fix_sigint()
# Set a file-descriptor as non-blocking
def set_nonblock(fd):
fcntl.fcntl(fd, fcntl.F_SETFL
, fcntl.fcntl(fd, fcntl.F_GETFL) | os.O_NONBLOCK)
# Clear HUPCL flag
def clear_hupcl(fd):
attrs = termios.tcgetattr(fd)
attrs[2] = attrs[2] & ~termios.HUPCL
termios.tcsetattr(fd, termios.TCSADRAIN, attrs)
# Support for creating a pseudo-tty for emulating a serial port
def create_pty(ptyname):
mfd, sfd = pty.openpty()
try:
os.unlink(ptyname)
except os.error:
pass
os.symlink(os.ttyname(sfd), ptyname)
fcntl.fcntl(mfd, fcntl.F_SETFL
, fcntl.fcntl(mfd, fcntl.F_GETFL) | os.O_NONBLOCK)
old = termios.tcgetattr(mfd)
old[3] = old[3] & ~termios.ECHO
termios.tcsetattr(mfd, termios.TCSADRAIN, old)
return mfd
def get_cpu_info():
try:
f = open('/proc/cpuinfo', 'rb')
data = f.read()
f.close()
except OSError:
logging.debug("Exception on read /proc/cpuinfo: %s" % (
traceback.format_exc(),))
return "?"
lines = [l.split(':', 1) for l in data.split('\n')]
lines = [(l[0].strip(), l[1].strip()) for l in lines if len(l) == 2]
core_count = [k for k, v in lines].count("processor")
model_name = dict(lines).get("model name", "?")
return "%d core %s" % (core_count, model_name)
def get_git_version():
# Obtain version info from "git" program
gitdir = os.path.join(sys.path[0], '..', '.git')
if not os.path.exists(gitdir):
logging.debug("No '.git' file/directory found")
return "?"
prog = "git --git-dir=%s describe --tags --long --dirty" % (gitdir,)
try:
process = subprocess.Popen(shlex.split(prog), stdout=subprocess.PIPE)
output = process.communicate()[0]
retcode = process.poll()
except OSError:
logging.debug("Exception on run: %s" % (traceback.format_exc(),))
return "?"
return output.strip()

16
lib/README Normal file
View File

@@ -0,0 +1,16 @@
This directory contains external library code.
The pjrc_usb_serial directory contains code from:
http://www.pjrc.com/teensy/usb_serial.html
version 1.7 (extracted on 20160605). It has been modified to compile
on recent versions of gcc. See usb_serial.patch for the modifications.
The cmsis-sam3x8e directory contains code from the Arduino project:
https://www.arduino.cc/
version 1.5.1 (extracted on 20160608). It has been modified to
compile with gcc's LTO feature. See cmsis-sam3x8e.patch for the
modifications.
The hub-ctrl directory contains code from:
https://github.com/codazoda/hub-ctrl.c/
revision 42095e522859059e8a5f4ec05c1e3def01a870a9.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,609 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V2.10
* @date 26. July 2011
*
* @note
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMFUNC_H
#define __CORE_CMFUNC_H
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/* intrinsic void __enable_irq(); */
/* intrinsic void __disable_irq(); */
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
static __INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
static __INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/** \brief Get ISPR Register
This function returns the content of the ISPR Register.
\return ISPR Register value
*/
static __INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
static __INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
static __INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
static __INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
static __INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
static __INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
static __INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
static __INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
static __INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
static __INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
static __INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xff);
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
static __INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
static __INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1);
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
static __INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
static __INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief Enable IRQ Interrupts
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __enable_irq(void)
{
__ASM volatile ("cpsie i");
}
/** \brief Disable IRQ Interrupts
This function disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __disable_irq(void)
{
__ASM volatile ("cpsid i");
}
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_CONTROL(void)
{
uint32_t result;
__ASM volatile ("MRS %0, control" : "=r" (result) );
return(result);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_CONTROL(uint32_t control)
{
__ASM volatile ("MSR control, %0" : : "r" (control) );
}
/** \brief Get ISPR Register
This function returns the content of the ISPR Register.
\return ISPR Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_IPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
return(result);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_APSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
return(result);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_xPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
return(result);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
return(result);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_PSP(uint32_t topOfProcStack)
{
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) );
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_MSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
return(result);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_MSP(uint32_t topOfMainStack)
{
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) );
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_PRIMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, primask" : "=r" (result) );
return(result);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_PRIMASK(uint32_t priMask)
{
__ASM volatile ("MSR primask, %0" : : "r" (priMask) );
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __enable_fault_irq(void)
{
__ASM volatile ("cpsie f");
}
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __disable_fault_irq(void)
{
__ASM volatile ("cpsid f");
}
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_BASEPRI(void)
{
uint32_t result;
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
return(result);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_BASEPRI(uint32_t value)
{
__ASM volatile ("MSR basepri, %0" : : "r" (value) );
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FAULTMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_FAULTMASK(uint32_t faultMask)
{
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) );
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
uint32_t result;
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
return(result);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__attribute__( ( always_inline ) ) static __INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) );
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all instrinsics,
* Including the CMSIS ones.
*/
#endif
/*@} end of CMSIS_Core_RegAccFunctions */
#endif /* __CORE_CMFUNC_H */

View File

@@ -0,0 +1,585 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V2.10
* @date 19. July 2011
*
* @note
* Copyright (C) 2009-2011 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef __CORE_CMINSTR_H
#define __CORE_CMINSTR_H
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
#define __WFI __wfi
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
#define __ISB() __isb(0xF)
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() __dsb(0xF)
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() __dmb(0xF)
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
static __INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
static __INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __RBIT __rbit
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXB(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXH(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXW(value, ptr) __strex(value, ptr)
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#endif /* (__CORTEX_M >= 0x03) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __NOP(void)
{
__ASM volatile ("nop");
}
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) static __INLINE void __WFI(void)
{
__ASM volatile ("wfi");
}
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) static __INLINE void __WFE(void)
{
__ASM volatile ("wfe");
}
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
__attribute__( ( always_inline ) ) static __INLINE void __SEV(void)
{
__ASM volatile ("sev");
}
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
__attribute__( ( always_inline ) ) static __INLINE void __ISB(void)
{
__ASM volatile ("isb");
}
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
__attribute__( ( always_inline ) ) static __INLINE void __DSB(void)
{
__ASM volatile ("dsb");
}
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
__attribute__( ( always_inline ) ) static __INLINE void __DMB(void)
{
__ASM volatile ("dmb");
}
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __REV16(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE int32_t __REVSH(int32_t value)
{
uint32_t result;
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__attribute__( ( always_inline ) ) static __INLINE uint8_t __LDREXB(volatile uint8_t *addr)
{
uint8_t result;
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__attribute__( ( always_inline ) ) static __INLINE uint16_t __LDREXH(volatile uint16_t *addr)
{
uint16_t result;
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __LDREXW(volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
uint32_t result;
__ASM volatile ("strexb %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
uint32_t result;
__ASM volatile ("strexh %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) static __INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("strex %0, %2, [%1]" : "=r" (result) : "r" (addr), "r" (value) );
return(result);
}
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
__attribute__( ( always_inline ) ) static __INLINE void __CLREX(void)
{
__ASM volatile ("clrex");
}
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
__attribute__( ( always_inline ) ) static __INLINE uint8_t __CLZ(uint32_t value)
{
uint8_t result;
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
#endif /* (__CORTEX_M >= 0x03) */
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#endif
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
#endif /* __CORE_CMINSTR_H */

View File

@@ -0,0 +1,11 @@
--- source/gcc/startup_sam3xa.c.orig 2016-06-14 14:20:43.166209461 -0400
+++ source/gcc/startup_sam3xa.c 2016-06-14 14:00:57.497137169 -0400
@@ -129,7 +129,7 @@
void CAN1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler")));
/* Exception Table */
-__attribute__ ((section(".vectors")))
+__attribute__ ((section(".vectors"))) __attribute__((externally_visible))
const DeviceVectors exception_table = {
/* Configure Initial Stack Pointer, using linker-generated symbols */

View File

@@ -0,0 +1,504 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2012, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _SAM3XA_ADC_COMPONENT_
#define _SAM3XA_ADC_COMPONENT_
/* ============================================================================= */
/** SOFTWARE API DEFINITION FOR Analog-to-digital Converter */
/* ============================================================================= */
/** \addtogroup SAM3XA_ADC Analog-to-digital Converter */
/*@{*/
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
/** \brief Adc hardware registers */
typedef struct {
WoReg ADC_CR; /**< \brief (Adc Offset: 0x00) Control Register */
RwReg ADC_MR; /**< \brief (Adc Offset: 0x04) Mode Register */
RwReg ADC_SEQR1; /**< \brief (Adc Offset: 0x08) Channel Sequence Register 1 */
RwReg ADC_SEQR2; /**< \brief (Adc Offset: 0x0C) Channel Sequence Register 2 */
WoReg ADC_CHER; /**< \brief (Adc Offset: 0x10) Channel Enable Register */
WoReg ADC_CHDR; /**< \brief (Adc Offset: 0x14) Channel Disable Register */
RoReg ADC_CHSR; /**< \brief (Adc Offset: 0x18) Channel Status Register */
RoReg Reserved1[1];
RoReg ADC_LCDR; /**< \brief (Adc Offset: 0x20) Last Converted Data Register */
WoReg ADC_IER; /**< \brief (Adc Offset: 0x24) Interrupt Enable Register */
WoReg ADC_IDR; /**< \brief (Adc Offset: 0x28) Interrupt Disable Register */
RoReg ADC_IMR; /**< \brief (Adc Offset: 0x2C) Interrupt Mask Register */
RoReg ADC_ISR; /**< \brief (Adc Offset: 0x30) Interrupt Status Register */
RoReg Reserved2[2];
RoReg ADC_OVER; /**< \brief (Adc Offset: 0x3C) Overrun Status Register */
RwReg ADC_EMR; /**< \brief (Adc Offset: 0x40) Extended Mode Register */
RwReg ADC_CWR; /**< \brief (Adc Offset: 0x44) Compare Window Register */
RwReg ADC_CGR; /**< \brief (Adc Offset: 0x48) Channel Gain Register */
RwReg ADC_COR; /**< \brief (Adc Offset: 0x4C) Channel Offset Register */
RoReg ADC_CDR[16]; /**< \brief (Adc Offset: 0x50) Channel Data Register */
RoReg Reserved3[1];
RwReg ADC_ACR; /**< \brief (Adc Offset: 0x94) Analog Control Register */
RoReg Reserved4[19];
RwReg ADC_WPMR; /**< \brief (Adc Offset: 0xE4) Write Protect Mode Register */
RoReg ADC_WPSR; /**< \brief (Adc Offset: 0xE8) Write Protect Status Register */
RoReg Reserved5[5];
RwReg ADC_RPR; /**< \brief (Adc Offset: 0x100) Receive Pointer Register */
RwReg ADC_RCR; /**< \brief (Adc Offset: 0x104) Receive Counter Register */
RoReg Reserved6[2];
RwReg ADC_RNPR; /**< \brief (Adc Offset: 0x110) Receive Next Pointer Register */
RwReg ADC_RNCR; /**< \brief (Adc Offset: 0x114) Receive Next Counter Register */
RoReg Reserved7[2];
WoReg ADC_PTCR; /**< \brief (Adc Offset: 0x120) Transfer Control Register */
RoReg ADC_PTSR; /**< \brief (Adc Offset: 0x124) Transfer Status Register */
} Adc;
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
/* -------- ADC_CR : (ADC Offset: 0x00) Control Register -------- */
#define ADC_CR_SWRST (0x1u << 0) /**< \brief (ADC_CR) Software Reset */
#define ADC_CR_START (0x1u << 1) /**< \brief (ADC_CR) Start Conversion */
/* -------- ADC_MR : (ADC Offset: 0x04) Mode Register -------- */
#define ADC_MR_TRGEN (0x1u << 0) /**< \brief (ADC_MR) Trigger Enable */
#define ADC_MR_TRGEN_DIS (0x0u << 0) /**< \brief (ADC_MR) Hardware triggers are disabled. Starting a conversion is only possible by software. */
#define ADC_MR_TRGEN_EN (0x1u << 0) /**< \brief (ADC_MR) Hardware trigger selected by TRGSEL field is enabled. */
#define ADC_MR_TRGSEL_Pos 1
#define ADC_MR_TRGSEL_Msk (0x7u << ADC_MR_TRGSEL_Pos) /**< \brief (ADC_MR) Trigger Selection */
#define ADC_MR_TRGSEL_ADC_TRIG0 (0x0u << 1) /**< \brief (ADC_MR) External : ADCTRG */
#define ADC_MR_TRGSEL_ADC_TRIG1 (0x1u << 1) /**< \brief (ADC_MR) TIOA Output of the Timer Counter Channel 0 */
#define ADC_MR_TRGSEL_ADC_TRIG2 (0x2u << 1) /**< \brief (ADC_MR) TIOA Output of the Timer Counter Channel 1 */
#define ADC_MR_TRGSEL_ADC_TRIG3 (0x3u << 1) /**< \brief (ADC_MR) TIOA Output of the Timer Counter Channel 2 */
#define ADC_MR_TRGSEL_ADC_TRIG4 (0x4u << 1) /**< \brief (ADC_MR) PWM Event Line 0 */
#define ADC_MR_TRGSEL_ADC_TRIG5 (0x5u << 1) /**< \brief (ADC_MR) PWM Event Line 0 */
#define ADC_MR_LOWRES (0x1u << 4) /**< \brief (ADC_MR) Resolution */
#define ADC_MR_LOWRES_BITS_12 (0x0u << 4) /**< \brief (ADC_MR) 12-bit resolution */
#define ADC_MR_LOWRES_BITS_10 (0x1u << 4) /**< \brief (ADC_MR) 10-bit resolution */
#define ADC_MR_SLEEP (0x1u << 5) /**< \brief (ADC_MR) Sleep Mode */
#define ADC_MR_SLEEP_NORMAL (0x0u << 5) /**< \brief (ADC_MR) Normal Mode: The ADC Core and reference voltage circuitry are kept ON between conversions */
#define ADC_MR_SLEEP_SLEEP (0x1u << 5) /**< \brief (ADC_MR) Sleep Mode: The ADC Core and reference voltage circuitry are OFF between conversions */
#define ADC_MR_FWUP (0x1u << 6) /**< \brief (ADC_MR) Fast Wake Up */
#define ADC_MR_FWUP_OFF (0x0u << 6) /**< \brief (ADC_MR) Normal Sleep Mode: The sleep mode is defined by the SLEEP bit */
#define ADC_MR_FWUP_ON (0x1u << 6) /**< \brief (ADC_MR) Fast Wake Up Sleep Mode: The Voltage reference is ON between conversions and ADC Core is OFF */
#define ADC_MR_FREERUN (0x1u << 7) /**< \brief (ADC_MR) Free Run Mode */
#define ADC_MR_FREERUN_OFF (0x0u << 7) /**< \brief (ADC_MR) Normal Mode */
#define ADC_MR_FREERUN_ON (0x1u << 7) /**< \brief (ADC_MR) Free Run Mode: Never wait for any trigger. */
#define ADC_MR_PRESCAL_Pos 8
#define ADC_MR_PRESCAL_Msk (0xffu << ADC_MR_PRESCAL_Pos) /**< \brief (ADC_MR) Prescaler Rate Selection */
#define ADC_MR_PRESCAL(value) ((ADC_MR_PRESCAL_Msk & ((value) << ADC_MR_PRESCAL_Pos)))
#define ADC_MR_STARTUP_Pos 16
#define ADC_MR_STARTUP_Msk (0xfu << ADC_MR_STARTUP_Pos) /**< \brief (ADC_MR) Start Up Time */
#define ADC_MR_STARTUP_SUT0 (0x0u << 16) /**< \brief (ADC_MR) 0 periods of ADCClock */
#define ADC_MR_STARTUP_SUT8 (0x1u << 16) /**< \brief (ADC_MR) 8 periods of ADCClock */
#define ADC_MR_STARTUP_SUT16 (0x2u << 16) /**< \brief (ADC_MR) 16 periods of ADCClock */
#define ADC_MR_STARTUP_SUT24 (0x3u << 16) /**< \brief (ADC_MR) 24 periods of ADCClock */
#define ADC_MR_STARTUP_SUT64 (0x4u << 16) /**< \brief (ADC_MR) 64 periods of ADCClock */
#define ADC_MR_STARTUP_SUT80 (0x5u << 16) /**< \brief (ADC_MR) 80 periods of ADCClock */
#define ADC_MR_STARTUP_SUT96 (0x6u << 16) /**< \brief (ADC_MR) 96 periods of ADCClock */
#define ADC_MR_STARTUP_SUT112 (0x7u << 16) /**< \brief (ADC_MR) 112 periods of ADCClock */
#define ADC_MR_STARTUP_SUT512 (0x8u << 16) /**< \brief (ADC_MR) 512 periods of ADCClock */
#define ADC_MR_STARTUP_SUT576 (0x9u << 16) /**< \brief (ADC_MR) 576 periods of ADCClock */
#define ADC_MR_STARTUP_SUT640 (0xAu << 16) /**< \brief (ADC_MR) 640 periods of ADCClock */
#define ADC_MR_STARTUP_SUT704 (0xBu << 16) /**< \brief (ADC_MR) 704 periods of ADCClock */
#define ADC_MR_STARTUP_SUT768 (0xCu << 16) /**< \brief (ADC_MR) 768 periods of ADCClock */
#define ADC_MR_STARTUP_SUT832 (0xDu << 16) /**< \brief (ADC_MR) 832 periods of ADCClock */
#define ADC_MR_STARTUP_SUT896 (0xEu << 16) /**< \brief (ADC_MR) 896 periods of ADCClock */
#define ADC_MR_STARTUP_SUT960 (0xFu << 16) /**< \brief (ADC_MR) 960 periods of ADCClock */
#define ADC_MR_SETTLING_Pos 20
#define ADC_MR_SETTLING_Msk (0x3u << ADC_MR_SETTLING_Pos) /**< \brief (ADC_MR) Analog Settling Time */
#define ADC_MR_SETTLING_AST3 (0x0u << 20) /**< \brief (ADC_MR) 3 periods of ADCClock */
#define ADC_MR_SETTLING_AST5 (0x1u << 20) /**< \brief (ADC_MR) 5 periods of ADCClock */
#define ADC_MR_SETTLING_AST9 (0x2u << 20) /**< \brief (ADC_MR) 9 periods of ADCClock */
#define ADC_MR_SETTLING_AST17 (0x3u << 20) /**< \brief (ADC_MR) 17 periods of ADCClock */
#define ADC_MR_ANACH (0x1u << 23) /**< \brief (ADC_MR) Analog Change */
#define ADC_MR_ANACH_NONE (0x0u << 23) /**< \brief (ADC_MR) No analog change on channel switching: DIFF0, GAIN0 and OFF0 are used for all channels */
#define ADC_MR_ANACH_ALLOWED (0x1u << 23) /**< \brief (ADC_MR) Allows different analog settings for each channel. See ADC_CGR and ADC_COR Registers */
#define ADC_MR_TRACKTIM_Pos 24
#define ADC_MR_TRACKTIM_Msk (0xfu << ADC_MR_TRACKTIM_Pos) /**< \brief (ADC_MR) Tracking Time */
#define ADC_MR_TRACKTIM(value) ((ADC_MR_TRACKTIM_Msk & ((value) << ADC_MR_TRACKTIM_Pos)))
#define ADC_MR_TRANSFER_Pos 28
#define ADC_MR_TRANSFER_Msk (0x3u << ADC_MR_TRANSFER_Pos) /**< \brief (ADC_MR) Transfer Period */
#define ADC_MR_TRANSFER(value) ((ADC_MR_TRANSFER_Msk & ((value) << ADC_MR_TRANSFER_Pos)))
#define ADC_MR_USEQ (0x1u << 31) /**< \brief (ADC_MR) Use Sequence Enable */
#define ADC_MR_USEQ_NUM_ORDER (0x0u << 31) /**< \brief (ADC_MR) Normal Mode: The controller converts channels in a simple numeric order. */
#define ADC_MR_USEQ_REG_ORDER (0x1u << 31) /**< \brief (ADC_MR) User Sequence Mode: The sequence respects what is defined in ADC_SEQR1 and ADC_SEQR2 registers. */
/* -------- ADC_SEQR1 : (ADC Offset: 0x08) Channel Sequence Register 1 -------- */
#define ADC_SEQR1_USCH1_Pos 0
#define ADC_SEQR1_USCH1_Msk (0xfu << ADC_SEQR1_USCH1_Pos) /**< \brief (ADC_SEQR1) User Sequence Number 1 */
#define ADC_SEQR1_USCH1(value) ((ADC_SEQR1_USCH1_Msk & ((value) << ADC_SEQR1_USCH1_Pos)))
#define ADC_SEQR1_USCH2_Pos 4
#define ADC_SEQR1_USCH2_Msk (0xfu << ADC_SEQR1_USCH2_Pos) /**< \brief (ADC_SEQR1) User Sequence Number 2 */
#define ADC_SEQR1_USCH2(value) ((ADC_SEQR1_USCH2_Msk & ((value) << ADC_SEQR1_USCH2_Pos)))
#define ADC_SEQR1_USCH3_Pos 8
#define ADC_SEQR1_USCH3_Msk (0xfu << ADC_SEQR1_USCH3_Pos) /**< \brief (ADC_SEQR1) User Sequence Number 3 */
#define ADC_SEQR1_USCH3(value) ((ADC_SEQR1_USCH3_Msk & ((value) << ADC_SEQR1_USCH3_Pos)))
#define ADC_SEQR1_USCH4_Pos 12
#define ADC_SEQR1_USCH4_Msk (0xfu << ADC_SEQR1_USCH4_Pos) /**< \brief (ADC_SEQR1) User Sequence Number 4 */
#define ADC_SEQR1_USCH4(value) ((ADC_SEQR1_USCH4_Msk & ((value) << ADC_SEQR1_USCH4_Pos)))
#define ADC_SEQR1_USCH5_Pos 16
#define ADC_SEQR1_USCH5_Msk (0xfu << ADC_SEQR1_USCH5_Pos) /**< \brief (ADC_SEQR1) User Sequence Number 5 */
#define ADC_SEQR1_USCH5(value) ((ADC_SEQR1_USCH5_Msk & ((value) << ADC_SEQR1_USCH5_Pos)))
#define ADC_SEQR1_USCH6_Pos 20
#define ADC_SEQR1_USCH6_Msk (0xfu << ADC_SEQR1_USCH6_Pos) /**< \brief (ADC_SEQR1) User Sequence Number 6 */
#define ADC_SEQR1_USCH6(value) ((ADC_SEQR1_USCH6_Msk & ((value) << ADC_SEQR1_USCH6_Pos)))
#define ADC_SEQR1_USCH7_Pos 24
#define ADC_SEQR1_USCH7_Msk (0xfu << ADC_SEQR1_USCH7_Pos) /**< \brief (ADC_SEQR1) User Sequence Number 7 */
#define ADC_SEQR1_USCH7(value) ((ADC_SEQR1_USCH7_Msk & ((value) << ADC_SEQR1_USCH7_Pos)))
#define ADC_SEQR1_USCH8_Pos 28
#define ADC_SEQR1_USCH8_Msk (0xfu << ADC_SEQR1_USCH8_Pos) /**< \brief (ADC_SEQR1) User Sequence Number 8 */
#define ADC_SEQR1_USCH8(value) ((ADC_SEQR1_USCH8_Msk & ((value) << ADC_SEQR1_USCH8_Pos)))
/* -------- ADC_SEQR2 : (ADC Offset: 0x0C) Channel Sequence Register 2 -------- */
#define ADC_SEQR2_USCH9_Pos 0
#define ADC_SEQR2_USCH9_Msk (0xfu << ADC_SEQR2_USCH9_Pos) /**< \brief (ADC_SEQR2) User Sequence Number 9 */
#define ADC_SEQR2_USCH9(value) ((ADC_SEQR2_USCH9_Msk & ((value) << ADC_SEQR2_USCH9_Pos)))
#define ADC_SEQR2_USCH10_Pos 4
#define ADC_SEQR2_USCH10_Msk (0xfu << ADC_SEQR2_USCH10_Pos) /**< \brief (ADC_SEQR2) User Sequence Number 10 */
#define ADC_SEQR2_USCH10(value) ((ADC_SEQR2_USCH10_Msk & ((value) << ADC_SEQR2_USCH10_Pos)))
#define ADC_SEQR2_USCH11_Pos 8
#define ADC_SEQR2_USCH11_Msk (0xfu << ADC_SEQR2_USCH11_Pos) /**< \brief (ADC_SEQR2) User Sequence Number 11 */
#define ADC_SEQR2_USCH11(value) ((ADC_SEQR2_USCH11_Msk & ((value) << ADC_SEQR2_USCH11_Pos)))
#define ADC_SEQR2_USCH12_Pos 12
#define ADC_SEQR2_USCH12_Msk (0xfu << ADC_SEQR2_USCH12_Pos) /**< \brief (ADC_SEQR2) User Sequence Number 12 */
#define ADC_SEQR2_USCH12(value) ((ADC_SEQR2_USCH12_Msk & ((value) << ADC_SEQR2_USCH12_Pos)))
#define ADC_SEQR2_USCH13_Pos 16
#define ADC_SEQR2_USCH13_Msk (0xfu << ADC_SEQR2_USCH13_Pos) /**< \brief (ADC_SEQR2) User Sequence Number 13 */
#define ADC_SEQR2_USCH13(value) ((ADC_SEQR2_USCH13_Msk & ((value) << ADC_SEQR2_USCH13_Pos)))
#define ADC_SEQR2_USCH14_Pos 20
#define ADC_SEQR2_USCH14_Msk (0xfu << ADC_SEQR2_USCH14_Pos) /**< \brief (ADC_SEQR2) User Sequence Number 14 */
#define ADC_SEQR2_USCH14(value) ((ADC_SEQR2_USCH14_Msk & ((value) << ADC_SEQR2_USCH14_Pos)))
#define ADC_SEQR2_USCH15_Pos 24
#define ADC_SEQR2_USCH15_Msk (0xfu << ADC_SEQR2_USCH15_Pos) /**< \brief (ADC_SEQR2) User Sequence Number 15 */
#define ADC_SEQR2_USCH15(value) ((ADC_SEQR2_USCH15_Msk & ((value) << ADC_SEQR2_USCH15_Pos)))
#define ADC_SEQR2_USCH16_Pos 28
#define ADC_SEQR2_USCH16_Msk (0xfu << ADC_SEQR2_USCH16_Pos) /**< \brief (ADC_SEQR2) User Sequence Number 16 */
#define ADC_SEQR2_USCH16(value) ((ADC_SEQR2_USCH16_Msk & ((value) << ADC_SEQR2_USCH16_Pos)))
/* -------- ADC_CHER : (ADC Offset: 0x10) Channel Enable Register -------- */
#define ADC_CHER_CH0 (0x1u << 0) /**< \brief (ADC_CHER) Channel 0 Enable */
#define ADC_CHER_CH1 (0x1u << 1) /**< \brief (ADC_CHER) Channel 1 Enable */
#define ADC_CHER_CH2 (0x1u << 2) /**< \brief (ADC_CHER) Channel 2 Enable */
#define ADC_CHER_CH3 (0x1u << 3) /**< \brief (ADC_CHER) Channel 3 Enable */
#define ADC_CHER_CH4 (0x1u << 4) /**< \brief (ADC_CHER) Channel 4 Enable */
#define ADC_CHER_CH5 (0x1u << 5) /**< \brief (ADC_CHER) Channel 5 Enable */
#define ADC_CHER_CH6 (0x1u << 6) /**< \brief (ADC_CHER) Channel 6 Enable */
#define ADC_CHER_CH7 (0x1u << 7) /**< \brief (ADC_CHER) Channel 7 Enable */
#define ADC_CHER_CH8 (0x1u << 8) /**< \brief (ADC_CHER) Channel 8 Enable */
#define ADC_CHER_CH9 (0x1u << 9) /**< \brief (ADC_CHER) Channel 9 Enable */
#define ADC_CHER_CH10 (0x1u << 10) /**< \brief (ADC_CHER) Channel 10 Enable */
#define ADC_CHER_CH11 (0x1u << 11) /**< \brief (ADC_CHER) Channel 11 Enable */
#define ADC_CHER_CH12 (0x1u << 12) /**< \brief (ADC_CHER) Channel 12 Enable */
#define ADC_CHER_CH13 (0x1u << 13) /**< \brief (ADC_CHER) Channel 13 Enable */
#define ADC_CHER_CH14 (0x1u << 14) /**< \brief (ADC_CHER) Channel 14 Enable */
#define ADC_CHER_CH15 (0x1u << 15) /**< \brief (ADC_CHER) Channel 15 Enable */
/* -------- ADC_CHDR : (ADC Offset: 0x14) Channel Disable Register -------- */
#define ADC_CHDR_CH0 (0x1u << 0) /**< \brief (ADC_CHDR) Channel 0 Disable */
#define ADC_CHDR_CH1 (0x1u << 1) /**< \brief (ADC_CHDR) Channel 1 Disable */
#define ADC_CHDR_CH2 (0x1u << 2) /**< \brief (ADC_CHDR) Channel 2 Disable */
#define ADC_CHDR_CH3 (0x1u << 3) /**< \brief (ADC_CHDR) Channel 3 Disable */
#define ADC_CHDR_CH4 (0x1u << 4) /**< \brief (ADC_CHDR) Channel 4 Disable */
#define ADC_CHDR_CH5 (0x1u << 5) /**< \brief (ADC_CHDR) Channel 5 Disable */
#define ADC_CHDR_CH6 (0x1u << 6) /**< \brief (ADC_CHDR) Channel 6 Disable */
#define ADC_CHDR_CH7 (0x1u << 7) /**< \brief (ADC_CHDR) Channel 7 Disable */
#define ADC_CHDR_CH8 (0x1u << 8) /**< \brief (ADC_CHDR) Channel 8 Disable */
#define ADC_CHDR_CH9 (0x1u << 9) /**< \brief (ADC_CHDR) Channel 9 Disable */
#define ADC_CHDR_CH10 (0x1u << 10) /**< \brief (ADC_CHDR) Channel 10 Disable */
#define ADC_CHDR_CH11 (0x1u << 11) /**< \brief (ADC_CHDR) Channel 11 Disable */
#define ADC_CHDR_CH12 (0x1u << 12) /**< \brief (ADC_CHDR) Channel 12 Disable */
#define ADC_CHDR_CH13 (0x1u << 13) /**< \brief (ADC_CHDR) Channel 13 Disable */
#define ADC_CHDR_CH14 (0x1u << 14) /**< \brief (ADC_CHDR) Channel 14 Disable */
#define ADC_CHDR_CH15 (0x1u << 15) /**< \brief (ADC_CHDR) Channel 15 Disable */
/* -------- ADC_CHSR : (ADC Offset: 0x18) Channel Status Register -------- */
#define ADC_CHSR_CH0 (0x1u << 0) /**< \brief (ADC_CHSR) Channel 0 Status */
#define ADC_CHSR_CH1 (0x1u << 1) /**< \brief (ADC_CHSR) Channel 1 Status */
#define ADC_CHSR_CH2 (0x1u << 2) /**< \brief (ADC_CHSR) Channel 2 Status */
#define ADC_CHSR_CH3 (0x1u << 3) /**< \brief (ADC_CHSR) Channel 3 Status */
#define ADC_CHSR_CH4 (0x1u << 4) /**< \brief (ADC_CHSR) Channel 4 Status */
#define ADC_CHSR_CH5 (0x1u << 5) /**< \brief (ADC_CHSR) Channel 5 Status */
#define ADC_CHSR_CH6 (0x1u << 6) /**< \brief (ADC_CHSR) Channel 6 Status */
#define ADC_CHSR_CH7 (0x1u << 7) /**< \brief (ADC_CHSR) Channel 7 Status */
#define ADC_CHSR_CH8 (0x1u << 8) /**< \brief (ADC_CHSR) Channel 8 Status */
#define ADC_CHSR_CH9 (0x1u << 9) /**< \brief (ADC_CHSR) Channel 9 Status */
#define ADC_CHSR_CH10 (0x1u << 10) /**< \brief (ADC_CHSR) Channel 10 Status */
#define ADC_CHSR_CH11 (0x1u << 11) /**< \brief (ADC_CHSR) Channel 11 Status */
#define ADC_CHSR_CH12 (0x1u << 12) /**< \brief (ADC_CHSR) Channel 12 Status */
#define ADC_CHSR_CH13 (0x1u << 13) /**< \brief (ADC_CHSR) Channel 13 Status */
#define ADC_CHSR_CH14 (0x1u << 14) /**< \brief (ADC_CHSR) Channel 14 Status */
#define ADC_CHSR_CH15 (0x1u << 15) /**< \brief (ADC_CHSR) Channel 15 Status */
/* -------- ADC_LCDR : (ADC Offset: 0x20) Last Converted Data Register -------- */
#define ADC_LCDR_LDATA_Pos 0
#define ADC_LCDR_LDATA_Msk (0xfffu << ADC_LCDR_LDATA_Pos) /**< \brief (ADC_LCDR) Last Data Converted */
#define ADC_LCDR_CHNB_Pos 12
#define ADC_LCDR_CHNB_Msk (0xfu << ADC_LCDR_CHNB_Pos) /**< \brief (ADC_LCDR) Channel Number */
/* -------- ADC_IER : (ADC Offset: 0x24) Interrupt Enable Register -------- */
#define ADC_IER_EOC0 (0x1u << 0) /**< \brief (ADC_IER) End of Conversion Interrupt Enable 0 */
#define ADC_IER_EOC1 (0x1u << 1) /**< \brief (ADC_IER) End of Conversion Interrupt Enable 1 */
#define ADC_IER_EOC2 (0x1u << 2) /**< \brief (ADC_IER) End of Conversion Interrupt Enable 2 */
#define ADC_IER_EOC3 (0x1u << 3) /**< \brief (ADC_IER) End of Conversion Interrupt Enable 3 */
#define ADC_IER_EOC4 (0x1u << 4) /**< \brief (ADC_IER) End of Conversion Interrupt Enable 4 */
#define ADC_IER_EOC5 (0x1u << 5) /**< \brief (ADC_IER) End of Conversion Interrupt Enable 5 */
#define ADC_IER_EOC6 (0x1u << 6) /**< \brief (ADC_IER) End of Conversion Interrupt Enable 6 */
#define ADC_IER_EOC7 (0x1u << 7) /**< \brief (ADC_IER) End of Conversion Interrupt Enable 7 */
#define ADC_IER_EOC8 (0x1u << 8) /**< \brief (ADC_IER) End of Conversion Interrupt Enable 8 */
#define ADC_IER_EOC9 (0x1u << 9) /**< \brief (ADC_IER) End of Conversion Interrupt Enable 9 */
#define ADC_IER_EOC10 (0x1u << 10) /**< \brief (ADC_IER) End of Conversion Interrupt Enable 10 */
#define ADC_IER_EOC11 (0x1u << 11) /**< \brief (ADC_IER) End of Conversion Interrupt Enable 11 */
#define ADC_IER_EOC12 (0x1u << 12) /**< \brief (ADC_IER) End of Conversion Interrupt Enable 12 */
#define ADC_IER_EOC13 (0x1u << 13) /**< \brief (ADC_IER) End of Conversion Interrupt Enable 13 */
#define ADC_IER_EOC14 (0x1u << 14) /**< \brief (ADC_IER) End of Conversion Interrupt Enable 14 */
#define ADC_IER_EOC15 (0x1u << 15) /**< \brief (ADC_IER) End of Conversion Interrupt Enable 15 */
#define ADC_IER_DRDY (0x1u << 24) /**< \brief (ADC_IER) Data Ready Interrupt Enable */
#define ADC_IER_GOVRE (0x1u << 25) /**< \brief (ADC_IER) General Overrun Error Interrupt Enable */
#define ADC_IER_COMPE (0x1u << 26) /**< \brief (ADC_IER) Comparison Event Interrupt Enable */
#define ADC_IER_ENDRX (0x1u << 27) /**< \brief (ADC_IER) End of Receive Buffer Interrupt Enable */
#define ADC_IER_RXBUFF (0x1u << 28) /**< \brief (ADC_IER) Receive Buffer Full Interrupt Enable */
/* -------- ADC_IDR : (ADC Offset: 0x28) Interrupt Disable Register -------- */
#define ADC_IDR_EOC0 (0x1u << 0) /**< \brief (ADC_IDR) End of Conversion Interrupt Disable 0 */
#define ADC_IDR_EOC1 (0x1u << 1) /**< \brief (ADC_IDR) End of Conversion Interrupt Disable 1 */
#define ADC_IDR_EOC2 (0x1u << 2) /**< \brief (ADC_IDR) End of Conversion Interrupt Disable 2 */
#define ADC_IDR_EOC3 (0x1u << 3) /**< \brief (ADC_IDR) End of Conversion Interrupt Disable 3 */
#define ADC_IDR_EOC4 (0x1u << 4) /**< \brief (ADC_IDR) End of Conversion Interrupt Disable 4 */
#define ADC_IDR_EOC5 (0x1u << 5) /**< \brief (ADC_IDR) End of Conversion Interrupt Disable 5 */
#define ADC_IDR_EOC6 (0x1u << 6) /**< \brief (ADC_IDR) End of Conversion Interrupt Disable 6 */
#define ADC_IDR_EOC7 (0x1u << 7) /**< \brief (ADC_IDR) End of Conversion Interrupt Disable 7 */
#define ADC_IDR_EOC8 (0x1u << 8) /**< \brief (ADC_IDR) End of Conversion Interrupt Disable 8 */
#define ADC_IDR_EOC9 (0x1u << 9) /**< \brief (ADC_IDR) End of Conversion Interrupt Disable 9 */
#define ADC_IDR_EOC10 (0x1u << 10) /**< \brief (ADC_IDR) End of Conversion Interrupt Disable 10 */
#define ADC_IDR_EOC11 (0x1u << 11) /**< \brief (ADC_IDR) End of Conversion Interrupt Disable 11 */
#define ADC_IDR_EOC12 (0x1u << 12) /**< \brief (ADC_IDR) End of Conversion Interrupt Disable 12 */
#define ADC_IDR_EOC13 (0x1u << 13) /**< \brief (ADC_IDR) End of Conversion Interrupt Disable 13 */
#define ADC_IDR_EOC14 (0x1u << 14) /**< \brief (ADC_IDR) End of Conversion Interrupt Disable 14 */
#define ADC_IDR_EOC15 (0x1u << 15) /**< \brief (ADC_IDR) End of Conversion Interrupt Disable 15 */
#define ADC_IDR_DRDY (0x1u << 24) /**< \brief (ADC_IDR) Data Ready Interrupt Disable */
#define ADC_IDR_GOVRE (0x1u << 25) /**< \brief (ADC_IDR) General Overrun Error Interrupt Disable */
#define ADC_IDR_COMPE (0x1u << 26) /**< \brief (ADC_IDR) Comparison Event Interrupt Disable */
#define ADC_IDR_ENDRX (0x1u << 27) /**< \brief (ADC_IDR) End of Receive Buffer Interrupt Disable */
#define ADC_IDR_RXBUFF (0x1u << 28) /**< \brief (ADC_IDR) Receive Buffer Full Interrupt Disable */
/* -------- ADC_IMR : (ADC Offset: 0x2C) Interrupt Mask Register -------- */
#define ADC_IMR_EOC0 (0x1u << 0) /**< \brief (ADC_IMR) End of Conversion Interrupt Mask 0 */
#define ADC_IMR_EOC1 (0x1u << 1) /**< \brief (ADC_IMR) End of Conversion Interrupt Mask 1 */
#define ADC_IMR_EOC2 (0x1u << 2) /**< \brief (ADC_IMR) End of Conversion Interrupt Mask 2 */
#define ADC_IMR_EOC3 (0x1u << 3) /**< \brief (ADC_IMR) End of Conversion Interrupt Mask 3 */
#define ADC_IMR_EOC4 (0x1u << 4) /**< \brief (ADC_IMR) End of Conversion Interrupt Mask 4 */
#define ADC_IMR_EOC5 (0x1u << 5) /**< \brief (ADC_IMR) End of Conversion Interrupt Mask 5 */
#define ADC_IMR_EOC6 (0x1u << 6) /**< \brief (ADC_IMR) End of Conversion Interrupt Mask 6 */
#define ADC_IMR_EOC7 (0x1u << 7) /**< \brief (ADC_IMR) End of Conversion Interrupt Mask 7 */
#define ADC_IMR_EOC8 (0x1u << 8) /**< \brief (ADC_IMR) End of Conversion Interrupt Mask 8 */
#define ADC_IMR_EOC9 (0x1u << 9) /**< \brief (ADC_IMR) End of Conversion Interrupt Mask 9 */
#define ADC_IMR_EOC10 (0x1u << 10) /**< \brief (ADC_IMR) End of Conversion Interrupt Mask 10 */
#define ADC_IMR_EOC11 (0x1u << 11) /**< \brief (ADC_IMR) End of Conversion Interrupt Mask 11 */
#define ADC_IMR_EOC12 (0x1u << 12) /**< \brief (ADC_IMR) End of Conversion Interrupt Mask 12 */
#define ADC_IMR_EOC13 (0x1u << 13) /**< \brief (ADC_IMR) End of Conversion Interrupt Mask 13 */
#define ADC_IMR_EOC14 (0x1u << 14) /**< \brief (ADC_IMR) End of Conversion Interrupt Mask 14 */
#define ADC_IMR_EOC15 (0x1u << 15) /**< \brief (ADC_IMR) End of Conversion Interrupt Mask 15 */
#define ADC_IMR_DRDY (0x1u << 24) /**< \brief (ADC_IMR) Data Ready Interrupt Mask */
#define ADC_IMR_GOVRE (0x1u << 25) /**< \brief (ADC_IMR) General Overrun Error Interrupt Mask */
#define ADC_IMR_COMPE (0x1u << 26) /**< \brief (ADC_IMR) Comparison Event Interrupt Mask */
#define ADC_IMR_ENDRX (0x1u << 27) /**< \brief (ADC_IMR) End of Receive Buffer Interrupt Mask */
#define ADC_IMR_RXBUFF (0x1u << 28) /**< \brief (ADC_IMR) Receive Buffer Full Interrupt Mask */
/* -------- ADC_ISR : (ADC Offset: 0x30) Interrupt Status Register -------- */
#define ADC_ISR_EOC0 (0x1u << 0) /**< \brief (ADC_ISR) End of Conversion 0 */
#define ADC_ISR_EOC1 (0x1u << 1) /**< \brief (ADC_ISR) End of Conversion 1 */
#define ADC_ISR_EOC2 (0x1u << 2) /**< \brief (ADC_ISR) End of Conversion 2 */
#define ADC_ISR_EOC3 (0x1u << 3) /**< \brief (ADC_ISR) End of Conversion 3 */
#define ADC_ISR_EOC4 (0x1u << 4) /**< \brief (ADC_ISR) End of Conversion 4 */
#define ADC_ISR_EOC5 (0x1u << 5) /**< \brief (ADC_ISR) End of Conversion 5 */
#define ADC_ISR_EOC6 (0x1u << 6) /**< \brief (ADC_ISR) End of Conversion 6 */
#define ADC_ISR_EOC7 (0x1u << 7) /**< \brief (ADC_ISR) End of Conversion 7 */
#define ADC_ISR_EOC8 (0x1u << 8) /**< \brief (ADC_ISR) End of Conversion 8 */
#define ADC_ISR_EOC9 (0x1u << 9) /**< \brief (ADC_ISR) End of Conversion 9 */
#define ADC_ISR_EOC10 (0x1u << 10) /**< \brief (ADC_ISR) End of Conversion 10 */
#define ADC_ISR_EOC11 (0x1u << 11) /**< \brief (ADC_ISR) End of Conversion 11 */
#define ADC_ISR_EOC12 (0x1u << 12) /**< \brief (ADC_ISR) End of Conversion 12 */
#define ADC_ISR_EOC13 (0x1u << 13) /**< \brief (ADC_ISR) End of Conversion 13 */
#define ADC_ISR_EOC14 (0x1u << 14) /**< \brief (ADC_ISR) End of Conversion 14 */
#define ADC_ISR_EOC15 (0x1u << 15) /**< \brief (ADC_ISR) End of Conversion 15 */
#define ADC_ISR_DRDY (0x1u << 24) /**< \brief (ADC_ISR) Data Ready */
#define ADC_ISR_GOVRE (0x1u << 25) /**< \brief (ADC_ISR) General Overrun Error */
#define ADC_ISR_COMPE (0x1u << 26) /**< \brief (ADC_ISR) Comparison Error */
#define ADC_ISR_ENDRX (0x1u << 27) /**< \brief (ADC_ISR) End of RX Buffer */
#define ADC_ISR_RXBUFF (0x1u << 28) /**< \brief (ADC_ISR) RX Buffer Full */
/* -------- ADC_OVER : (ADC Offset: 0x3C) Overrun Status Register -------- */
#define ADC_OVER_OVRE0 (0x1u << 0) /**< \brief (ADC_OVER) Overrun Error 0 */
#define ADC_OVER_OVRE1 (0x1u << 1) /**< \brief (ADC_OVER) Overrun Error 1 */
#define ADC_OVER_OVRE2 (0x1u << 2) /**< \brief (ADC_OVER) Overrun Error 2 */
#define ADC_OVER_OVRE3 (0x1u << 3) /**< \brief (ADC_OVER) Overrun Error 3 */
#define ADC_OVER_OVRE4 (0x1u << 4) /**< \brief (ADC_OVER) Overrun Error 4 */
#define ADC_OVER_OVRE5 (0x1u << 5) /**< \brief (ADC_OVER) Overrun Error 5 */
#define ADC_OVER_OVRE6 (0x1u << 6) /**< \brief (ADC_OVER) Overrun Error 6 */
#define ADC_OVER_OVRE7 (0x1u << 7) /**< \brief (ADC_OVER) Overrun Error 7 */
#define ADC_OVER_OVRE8 (0x1u << 8) /**< \brief (ADC_OVER) Overrun Error 8 */
#define ADC_OVER_OVRE9 (0x1u << 9) /**< \brief (ADC_OVER) Overrun Error 9 */
#define ADC_OVER_OVRE10 (0x1u << 10) /**< \brief (ADC_OVER) Overrun Error 10 */
#define ADC_OVER_OVRE11 (0x1u << 11) /**< \brief (ADC_OVER) Overrun Error 11 */
#define ADC_OVER_OVRE12 (0x1u << 12) /**< \brief (ADC_OVER) Overrun Error 12 */
#define ADC_OVER_OVRE13 (0x1u << 13) /**< \brief (ADC_OVER) Overrun Error 13 */
#define ADC_OVER_OVRE14 (0x1u << 14) /**< \brief (ADC_OVER) Overrun Error 14 */
#define ADC_OVER_OVRE15 (0x1u << 15) /**< \brief (ADC_OVER) Overrun Error 15 */
/* -------- ADC_EMR : (ADC Offset: 0x40) Extended Mode Register -------- */
#define ADC_EMR_CMPMODE_Pos 0
#define ADC_EMR_CMPMODE_Msk (0x3u << ADC_EMR_CMPMODE_Pos) /**< \brief (ADC_EMR) Comparison Mode */
#define ADC_EMR_CMPMODE_LOW (0x0u << 0) /**< \brief (ADC_EMR) Generates an event when the converted data is lower than the low threshold of the window. */
#define ADC_EMR_CMPMODE_HIGH (0x1u << 0) /**< \brief (ADC_EMR) Generates an event when the converted data is higher than the high threshold of the window. */
#define ADC_EMR_CMPMODE_IN (0x2u << 0) /**< \brief (ADC_EMR) Generates an event when the converted data is in the comparison window. */
#define ADC_EMR_CMPMODE_OUT (0x3u << 0) /**< \brief (ADC_EMR) Generates an event when the converted data is out of the comparison window. */
#define ADC_EMR_CMPSEL_Pos 4
#define ADC_EMR_CMPSEL_Msk (0xfu << ADC_EMR_CMPSEL_Pos) /**< \brief (ADC_EMR) Comparison Selected Channel */
#define ADC_EMR_CMPSEL(value) ((ADC_EMR_CMPSEL_Msk & ((value) << ADC_EMR_CMPSEL_Pos)))
#define ADC_EMR_CMPALL (0x1u << 9) /**< \brief (ADC_EMR) Compare All Channels */
#define ADC_EMR_CMPFILTER_Pos 12
#define ADC_EMR_CMPFILTER_Msk (0x3u << ADC_EMR_CMPFILTER_Pos) /**< \brief (ADC_EMR) Compare Event Filtering */
#define ADC_EMR_CMPFILTER(value) ((ADC_EMR_CMPFILTER_Msk & ((value) << ADC_EMR_CMPFILTER_Pos)))
#define ADC_EMR_TAG (0x1u << 24) /**< \brief (ADC_EMR) TAG of ADC_LDCR register */
/* -------- ADC_CWR : (ADC Offset: 0x44) Compare Window Register -------- */
#define ADC_CWR_LOWTHRES_Pos 0
#define ADC_CWR_LOWTHRES_Msk (0xfffu << ADC_CWR_LOWTHRES_Pos) /**< \brief (ADC_CWR) Low Threshold */
#define ADC_CWR_LOWTHRES(value) ((ADC_CWR_LOWTHRES_Msk & ((value) << ADC_CWR_LOWTHRES_Pos)))
#define ADC_CWR_HIGHTHRES_Pos 16
#define ADC_CWR_HIGHTHRES_Msk (0xfffu << ADC_CWR_HIGHTHRES_Pos) /**< \brief (ADC_CWR) High Threshold */
#define ADC_CWR_HIGHTHRES(value) ((ADC_CWR_HIGHTHRES_Msk & ((value) << ADC_CWR_HIGHTHRES_Pos)))
/* -------- ADC_CGR : (ADC Offset: 0x48) Channel Gain Register -------- */
#define ADC_CGR_GAIN0_Pos 0
#define ADC_CGR_GAIN0_Msk (0x3u << ADC_CGR_GAIN0_Pos) /**< \brief (ADC_CGR) Gain for channel 0 */
#define ADC_CGR_GAIN0(value) ((ADC_CGR_GAIN0_Msk & ((value) << ADC_CGR_GAIN0_Pos)))
#define ADC_CGR_GAIN1_Pos 2
#define ADC_CGR_GAIN1_Msk (0x3u << ADC_CGR_GAIN1_Pos) /**< \brief (ADC_CGR) Gain for channel 1 */
#define ADC_CGR_GAIN1(value) ((ADC_CGR_GAIN1_Msk & ((value) << ADC_CGR_GAIN1_Pos)))
#define ADC_CGR_GAIN2_Pos 4
#define ADC_CGR_GAIN2_Msk (0x3u << ADC_CGR_GAIN2_Pos) /**< \brief (ADC_CGR) Gain for channel 2 */
#define ADC_CGR_GAIN2(value) ((ADC_CGR_GAIN2_Msk & ((value) << ADC_CGR_GAIN2_Pos)))
#define ADC_CGR_GAIN3_Pos 6
#define ADC_CGR_GAIN3_Msk (0x3u << ADC_CGR_GAIN3_Pos) /**< \brief (ADC_CGR) Gain for channel 3 */
#define ADC_CGR_GAIN3(value) ((ADC_CGR_GAIN3_Msk & ((value) << ADC_CGR_GAIN3_Pos)))
#define ADC_CGR_GAIN4_Pos 8
#define ADC_CGR_GAIN4_Msk (0x3u << ADC_CGR_GAIN4_Pos) /**< \brief (ADC_CGR) Gain for channel 4 */
#define ADC_CGR_GAIN4(value) ((ADC_CGR_GAIN4_Msk & ((value) << ADC_CGR_GAIN4_Pos)))
#define ADC_CGR_GAIN5_Pos 10
#define ADC_CGR_GAIN5_Msk (0x3u << ADC_CGR_GAIN5_Pos) /**< \brief (ADC_CGR) Gain for channel 5 */
#define ADC_CGR_GAIN5(value) ((ADC_CGR_GAIN5_Msk & ((value) << ADC_CGR_GAIN5_Pos)))
#define ADC_CGR_GAIN6_Pos 12
#define ADC_CGR_GAIN6_Msk (0x3u << ADC_CGR_GAIN6_Pos) /**< \brief (ADC_CGR) Gain for channel 6 */
#define ADC_CGR_GAIN6(value) ((ADC_CGR_GAIN6_Msk & ((value) << ADC_CGR_GAIN6_Pos)))
#define ADC_CGR_GAIN7_Pos 14
#define ADC_CGR_GAIN7_Msk (0x3u << ADC_CGR_GAIN7_Pos) /**< \brief (ADC_CGR) Gain for channel 7 */
#define ADC_CGR_GAIN7(value) ((ADC_CGR_GAIN7_Msk & ((value) << ADC_CGR_GAIN7_Pos)))
#define ADC_CGR_GAIN8_Pos 16
#define ADC_CGR_GAIN8_Msk (0x3u << ADC_CGR_GAIN8_Pos) /**< \brief (ADC_CGR) Gain for channel 8 */
#define ADC_CGR_GAIN8(value) ((ADC_CGR_GAIN8_Msk & ((value) << ADC_CGR_GAIN8_Pos)))
#define ADC_CGR_GAIN9_Pos 18
#define ADC_CGR_GAIN9_Msk (0x3u << ADC_CGR_GAIN9_Pos) /**< \brief (ADC_CGR) Gain for channel 9 */
#define ADC_CGR_GAIN9(value) ((ADC_CGR_GAIN9_Msk & ((value) << ADC_CGR_GAIN9_Pos)))
#define ADC_CGR_GAIN10_Pos 20
#define ADC_CGR_GAIN10_Msk (0x3u << ADC_CGR_GAIN10_Pos) /**< \brief (ADC_CGR) Gain for channel 10 */
#define ADC_CGR_GAIN10(value) ((ADC_CGR_GAIN10_Msk & ((value) << ADC_CGR_GAIN10_Pos)))
#define ADC_CGR_GAIN11_Pos 22
#define ADC_CGR_GAIN11_Msk (0x3u << ADC_CGR_GAIN11_Pos) /**< \brief (ADC_CGR) Gain for channel 11 */
#define ADC_CGR_GAIN11(value) ((ADC_CGR_GAIN11_Msk & ((value) << ADC_CGR_GAIN11_Pos)))
#define ADC_CGR_GAIN12_Pos 24
#define ADC_CGR_GAIN12_Msk (0x3u << ADC_CGR_GAIN12_Pos) /**< \brief (ADC_CGR) Gain for channel 12 */
#define ADC_CGR_GAIN12(value) ((ADC_CGR_GAIN12_Msk & ((value) << ADC_CGR_GAIN12_Pos)))
#define ADC_CGR_GAIN13_Pos 26
#define ADC_CGR_GAIN13_Msk (0x3u << ADC_CGR_GAIN13_Pos) /**< \brief (ADC_CGR) Gain for channel 13 */
#define ADC_CGR_GAIN13(value) ((ADC_CGR_GAIN13_Msk & ((value) << ADC_CGR_GAIN13_Pos)))
#define ADC_CGR_GAIN14_Pos 28
#define ADC_CGR_GAIN14_Msk (0x3u << ADC_CGR_GAIN14_Pos) /**< \brief (ADC_CGR) Gain for channel 14 */
#define ADC_CGR_GAIN14(value) ((ADC_CGR_GAIN14_Msk & ((value) << ADC_CGR_GAIN14_Pos)))
#define ADC_CGR_GAIN15_Pos 30
#define ADC_CGR_GAIN15_Msk (0x3u << ADC_CGR_GAIN15_Pos) /**< \brief (ADC_CGR) Gain for channel 15 */
#define ADC_CGR_GAIN15(value) ((ADC_CGR_GAIN15_Msk & ((value) << ADC_CGR_GAIN15_Pos)))
/* -------- ADC_COR : (ADC Offset: 0x4C) Channel Offset Register -------- */
#define ADC_COR_OFF0 (0x1u << 0) /**< \brief (ADC_COR) Offset for channel 0 */
#define ADC_COR_OFF1 (0x1u << 1) /**< \brief (ADC_COR) Offset for channel 1 */
#define ADC_COR_OFF2 (0x1u << 2) /**< \brief (ADC_COR) Offset for channel 2 */
#define ADC_COR_OFF3 (0x1u << 3) /**< \brief (ADC_COR) Offset for channel 3 */
#define ADC_COR_OFF4 (0x1u << 4) /**< \brief (ADC_COR) Offset for channel 4 */
#define ADC_COR_OFF5 (0x1u << 5) /**< \brief (ADC_COR) Offset for channel 5 */
#define ADC_COR_OFF6 (0x1u << 6) /**< \brief (ADC_COR) Offset for channel 6 */
#define ADC_COR_OFF7 (0x1u << 7) /**< \brief (ADC_COR) Offset for channel 7 */
#define ADC_COR_OFF8 (0x1u << 8) /**< \brief (ADC_COR) Offset for channel 8 */
#define ADC_COR_OFF9 (0x1u << 9) /**< \brief (ADC_COR) Offset for channel 9 */
#define ADC_COR_OFF10 (0x1u << 10) /**< \brief (ADC_COR) Offset for channel 10 */
#define ADC_COR_OFF11 (0x1u << 11) /**< \brief (ADC_COR) Offset for channel 11 */
#define ADC_COR_OFF12 (0x1u << 12) /**< \brief (ADC_COR) Offset for channel 12 */
#define ADC_COR_OFF13 (0x1u << 13) /**< \brief (ADC_COR) Offset for channel 13 */
#define ADC_COR_OFF14 (0x1u << 14) /**< \brief (ADC_COR) Offset for channel 14 */
#define ADC_COR_OFF15 (0x1u << 15) /**< \brief (ADC_COR) Offset for channel 15 */
#define ADC_COR_DIFF0 (0x1u << 16) /**< \brief (ADC_COR) Differential inputs for channel 0 */
#define ADC_COR_DIFF1 (0x1u << 17) /**< \brief (ADC_COR) Differential inputs for channel 1 */
#define ADC_COR_DIFF2 (0x1u << 18) /**< \brief (ADC_COR) Differential inputs for channel 2 */
#define ADC_COR_DIFF3 (0x1u << 19) /**< \brief (ADC_COR) Differential inputs for channel 3 */
#define ADC_COR_DIFF4 (0x1u << 20) /**< \brief (ADC_COR) Differential inputs for channel 4 */
#define ADC_COR_DIFF5 (0x1u << 21) /**< \brief (ADC_COR) Differential inputs for channel 5 */
#define ADC_COR_DIFF6 (0x1u << 22) /**< \brief (ADC_COR) Differential inputs for channel 6 */
#define ADC_COR_DIFF7 (0x1u << 23) /**< \brief (ADC_COR) Differential inputs for channel 7 */
#define ADC_COR_DIFF8 (0x1u << 24) /**< \brief (ADC_COR) Differential inputs for channel 8 */
#define ADC_COR_DIFF9 (0x1u << 25) /**< \brief (ADC_COR) Differential inputs for channel 9 */
#define ADC_COR_DIFF10 (0x1u << 26) /**< \brief (ADC_COR) Differential inputs for channel 10 */
#define ADC_COR_DIFF11 (0x1u << 27) /**< \brief (ADC_COR) Differential inputs for channel 11 */
#define ADC_COR_DIFF12 (0x1u << 28) /**< \brief (ADC_COR) Differential inputs for channel 12 */
#define ADC_COR_DIFF13 (0x1u << 29) /**< \brief (ADC_COR) Differential inputs for channel 13 */
#define ADC_COR_DIFF14 (0x1u << 30) /**< \brief (ADC_COR) Differential inputs for channel 14 */
#define ADC_COR_DIFF15 (0x1u << 31) /**< \brief (ADC_COR) Differential inputs for channel 15 */
/* -------- ADC_CDR[16] : (ADC Offset: 0x50) Channel Data Register -------- */
#define ADC_CDR_DATA_Pos 0
#define ADC_CDR_DATA_Msk (0xfffu << ADC_CDR_DATA_Pos) /**< \brief (ADC_CDR[16]) Converted Data */
/* -------- ADC_ACR : (ADC Offset: 0x94) Analog Control Register -------- */
#define ADC_ACR_TSON (0x1u << 4) /**< \brief (ADC_ACR) Temperature Sensor On */
#define ADC_ACR_IBCTL_Pos 8
#define ADC_ACR_IBCTL_Msk (0x3u << ADC_ACR_IBCTL_Pos) /**< \brief (ADC_ACR) ADC Bias Current Control */
#define ADC_ACR_IBCTL(value) ((ADC_ACR_IBCTL_Msk & ((value) << ADC_ACR_IBCTL_Pos)))
/* -------- ADC_WPMR : (ADC Offset: 0xE4) Write Protect Mode Register -------- */
#define ADC_WPMR_WPEN (0x1u << 0) /**< \brief (ADC_WPMR) Write Protect Enable */
#define ADC_WPMR_WPKEY_Pos 8
#define ADC_WPMR_WPKEY_Msk (0xffffffu << ADC_WPMR_WPKEY_Pos) /**< \brief (ADC_WPMR) Write Protect KEY */
#define ADC_WPMR_WPKEY(value) ((ADC_WPMR_WPKEY_Msk & ((value) << ADC_WPMR_WPKEY_Pos)))
/* -------- ADC_WPSR : (ADC Offset: 0xE8) Write Protect Status Register -------- */
#define ADC_WPSR_WPVS (0x1u << 0) /**< \brief (ADC_WPSR) Write Protect Violation Status */
#define ADC_WPSR_WPVSRC_Pos 8
#define ADC_WPSR_WPVSRC_Msk (0xffffu << ADC_WPSR_WPVSRC_Pos) /**< \brief (ADC_WPSR) Write Protect Violation Source */
/* -------- ADC_RPR : (ADC Offset: 0x100) Receive Pointer Register -------- */
#define ADC_RPR_RXPTR_Pos 0
#define ADC_RPR_RXPTR_Msk (0xffffffffu << ADC_RPR_RXPTR_Pos) /**< \brief (ADC_RPR) Receive Pointer Register */
#define ADC_RPR_RXPTR(value) ((ADC_RPR_RXPTR_Msk & ((value) << ADC_RPR_RXPTR_Pos)))
/* -------- ADC_RCR : (ADC Offset: 0x104) Receive Counter Register -------- */
#define ADC_RCR_RXCTR_Pos 0
#define ADC_RCR_RXCTR_Msk (0xffffu << ADC_RCR_RXCTR_Pos) /**< \brief (ADC_RCR) Receive Counter Register */
#define ADC_RCR_RXCTR(value) ((ADC_RCR_RXCTR_Msk & ((value) << ADC_RCR_RXCTR_Pos)))
/* -------- ADC_RNPR : (ADC Offset: 0x110) Receive Next Pointer Register -------- */
#define ADC_RNPR_RXNPTR_Pos 0
#define ADC_RNPR_RXNPTR_Msk (0xffffffffu << ADC_RNPR_RXNPTR_Pos) /**< \brief (ADC_RNPR) Receive Next Pointer */
#define ADC_RNPR_RXNPTR(value) ((ADC_RNPR_RXNPTR_Msk & ((value) << ADC_RNPR_RXNPTR_Pos)))
/* -------- ADC_RNCR : (ADC Offset: 0x114) Receive Next Counter Register -------- */
#define ADC_RNCR_RXNCTR_Pos 0
#define ADC_RNCR_RXNCTR_Msk (0xffffu << ADC_RNCR_RXNCTR_Pos) /**< \brief (ADC_RNCR) Receive Next Counter */
#define ADC_RNCR_RXNCTR(value) ((ADC_RNCR_RXNCTR_Msk & ((value) << ADC_RNCR_RXNCTR_Pos)))
/* -------- ADC_PTCR : (ADC Offset: 0x120) Transfer Control Register -------- */
#define ADC_PTCR_RXTEN (0x1u << 0) /**< \brief (ADC_PTCR) Receiver Transfer Enable */
#define ADC_PTCR_RXTDIS (0x1u << 1) /**< \brief (ADC_PTCR) Receiver Transfer Disable */
#define ADC_PTCR_TXTEN (0x1u << 8) /**< \brief (ADC_PTCR) Transmitter Transfer Enable */
#define ADC_PTCR_TXTDIS (0x1u << 9) /**< \brief (ADC_PTCR) Transmitter Transfer Disable */
/* -------- ADC_PTSR : (ADC Offset: 0x124) Transfer Status Register -------- */
#define ADC_PTSR_RXTEN (0x1u << 0) /**< \brief (ADC_PTSR) Receiver Transfer Enable */
#define ADC_PTSR_TXTEN (0x1u << 8) /**< \brief (ADC_PTSR) Transmitter Transfer Enable */
/*@}*/
#endif /* _SAM3XA_ADC_COMPONENT_ */

View File

@@ -0,0 +1,298 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2012, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _SAM3XA_CAN_COMPONENT_
#define _SAM3XA_CAN_COMPONENT_
/* ============================================================================= */
/** SOFTWARE API DEFINITION FOR Controller Area Network */
/* ============================================================================= */
/** \addtogroup SAM3XA_CAN Controller Area Network */
/*@{*/
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
/** \brief CanMb hardware registers */
typedef struct {
RwReg CAN_MMR; /**< \brief (CanMb Offset: 0x0) Mailbox Mode Register */
RwReg CAN_MAM; /**< \brief (CanMb Offset: 0x4) Mailbox Acceptance Mask Register */
RwReg CAN_MID; /**< \brief (CanMb Offset: 0x8) Mailbox ID Register */
RwReg CAN_MFID; /**< \brief (CanMb Offset: 0xC) Mailbox Family ID Register */
RwReg CAN_MSR; /**< \brief (CanMb Offset: 0x10) Mailbox Status Register */
RwReg CAN_MDL; /**< \brief (CanMb Offset: 0x14) Mailbox Data Low Register */
RwReg CAN_MDH; /**< \brief (CanMb Offset: 0x18) Mailbox Data High Register */
RwReg CAN_MCR; /**< \brief (CanMb Offset: 0x1C) Mailbox Control Register */
} CanMb;
/** \brief Can hardware registers */
#define CANMB_NUMBER 8
typedef struct {
RwReg CAN_MR; /**< \brief (Can Offset: 0x0000) Mode Register */
WoReg CAN_IER; /**< \brief (Can Offset: 0x0004) Interrupt Enable Register */
WoReg CAN_IDR; /**< \brief (Can Offset: 0x0008) Interrupt Disable Register */
RoReg CAN_IMR; /**< \brief (Can Offset: 0x000C) Interrupt Mask Register */
RoReg CAN_SR; /**< \brief (Can Offset: 0x0010) Status Register */
RwReg CAN_BR; /**< \brief (Can Offset: 0x0014) Baudrate Register */
RoReg CAN_TIM; /**< \brief (Can Offset: 0x0018) Timer Register */
RoReg CAN_TIMESTP; /**< \brief (Can Offset: 0x001C) Timestamp Register */
RoReg CAN_ECR; /**< \brief (Can Offset: 0x0020) Error Counter Register */
WoReg CAN_TCR; /**< \brief (Can Offset: 0x0024) Transfer Command Register */
WoReg CAN_ACR; /**< \brief (Can Offset: 0x0028) Abort Command Register */
RoReg Reserved1[46];
RwReg CAN_WPMR; /**< \brief (Can Offset: 0x00E4) Write Protect Mode Register */
RoReg CAN_WPSR; /**< \brief (Can Offset: 0x00E8) Write Protect Status Register */
RoReg Reserved2[69];
CanMb CAN_MB[CANMB_NUMBER]; /**< \brief (Can Offset: 0x200) MB = 0 .. 7 */
} Can;
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
/* -------- CAN_MR : (CAN Offset: 0x0000) Mode Register -------- */
#define CAN_MR_CANEN (0x1u << 0) /**< \brief (CAN_MR) CAN Controller Enable */
#define CAN_MR_LPM (0x1u << 1) /**< \brief (CAN_MR) Disable/Enable Low Power Mode */
#define CAN_MR_ABM (0x1u << 2) /**< \brief (CAN_MR) Disable/Enable Autobaud/Listen mode */
#define CAN_MR_OVL (0x1u << 3) /**< \brief (CAN_MR) Disable/Enable Overload Frame */
#define CAN_MR_TEOF (0x1u << 4) /**< \brief (CAN_MR) Timestamp messages at each end of Frame */
#define CAN_MR_TTM (0x1u << 5) /**< \brief (CAN_MR) Disable/Enable Time Triggered Mode */
#define CAN_MR_TIMFRZ (0x1u << 6) /**< \brief (CAN_MR) Enable Timer Freeze */
#define CAN_MR_DRPT (0x1u << 7) /**< \brief (CAN_MR) Disable Repeat */
#define CAN_MR_RXSYNC_Pos 24
#define CAN_MR_RXSYNC_Msk (0x7u << CAN_MR_RXSYNC_Pos) /**< \brief (CAN_MR) Reception Synchronization Stage (not readable) */
#define CAN_MR_RXSYNC_DOUBLE_PP (0x0u << 24) /**< \brief (CAN_MR) Rx Signal with Double Synchro Stages (2 Positive Edges) */
#define CAN_MR_RXSYNC_DOUBLE_PN (0x1u << 24) /**< \brief (CAN_MR) Rx Signal with Double Synchro Stages (One Positive Edge and One Negative Edge) */
#define CAN_MR_RXSYNC_SINGLE_P (0x2u << 24) /**< \brief (CAN_MR) Rx Signal with Single Synchro Stage (Positive Edge) */
#define CAN_MR_RXSYNC_NONE (0x3u << 24) /**< \brief (CAN_MR) Rx Signal with No Synchro Stage */
/* -------- CAN_IER : (CAN Offset: 0x0004) Interrupt Enable Register -------- */
#define CAN_IER_MB0 (0x1u << 0) /**< \brief (CAN_IER) Mailbox 0 Interrupt Enable */
#define CAN_IER_MB1 (0x1u << 1) /**< \brief (CAN_IER) Mailbox 1 Interrupt Enable */
#define CAN_IER_MB2 (0x1u << 2) /**< \brief (CAN_IER) Mailbox 2 Interrupt Enable */
#define CAN_IER_MB3 (0x1u << 3) /**< \brief (CAN_IER) Mailbox 3 Interrupt Enable */
#define CAN_IER_MB4 (0x1u << 4) /**< \brief (CAN_IER) Mailbox 4 Interrupt Enable */
#define CAN_IER_MB5 (0x1u << 5) /**< \brief (CAN_IER) Mailbox 5 Interrupt Enable */
#define CAN_IER_MB6 (0x1u << 6) /**< \brief (CAN_IER) Mailbox 6 Interrupt Enable */
#define CAN_IER_MB7 (0x1u << 7) /**< \brief (CAN_IER) Mailbox 7 Interrupt Enable */
#define CAN_IER_ERRA (0x1u << 16) /**< \brief (CAN_IER) Error Active Mode Interrupt Enable */
#define CAN_IER_WARN (0x1u << 17) /**< \brief (CAN_IER) Warning Limit Interrupt Enable */
#define CAN_IER_ERRP (0x1u << 18) /**< \brief (CAN_IER) Error Passive Mode Interrupt Enable */
#define CAN_IER_BOFF (0x1u << 19) /**< \brief (CAN_IER) Bus Off Mode Interrupt Enable */
#define CAN_IER_SLEEP (0x1u << 20) /**< \brief (CAN_IER) Sleep Interrupt Enable */
#define CAN_IER_WAKEUP (0x1u << 21) /**< \brief (CAN_IER) Wakeup Interrupt Enable */
#define CAN_IER_TOVF (0x1u << 22) /**< \brief (CAN_IER) Timer Overflow Interrupt Enable */
#define CAN_IER_TSTP (0x1u << 23) /**< \brief (CAN_IER) TimeStamp Interrupt Enable */
#define CAN_IER_CERR (0x1u << 24) /**< \brief (CAN_IER) CRC Error Interrupt Enable */
#define CAN_IER_SERR (0x1u << 25) /**< \brief (CAN_IER) Stuffing Error Interrupt Enable */
#define CAN_IER_AERR (0x1u << 26) /**< \brief (CAN_IER) Acknowledgment Error Interrupt Enable */
#define CAN_IER_FERR (0x1u << 27) /**< \brief (CAN_IER) Form Error Interrupt Enable */
#define CAN_IER_BERR (0x1u << 28) /**< \brief (CAN_IER) Bit Error Interrupt Enable */
/* -------- CAN_IDR : (CAN Offset: 0x0008) Interrupt Disable Register -------- */
#define CAN_IDR_MB0 (0x1u << 0) /**< \brief (CAN_IDR) Mailbox 0 Interrupt Disable */
#define CAN_IDR_MB1 (0x1u << 1) /**< \brief (CAN_IDR) Mailbox 1 Interrupt Disable */
#define CAN_IDR_MB2 (0x1u << 2) /**< \brief (CAN_IDR) Mailbox 2 Interrupt Disable */
#define CAN_IDR_MB3 (0x1u << 3) /**< \brief (CAN_IDR) Mailbox 3 Interrupt Disable */
#define CAN_IDR_MB4 (0x1u << 4) /**< \brief (CAN_IDR) Mailbox 4 Interrupt Disable */
#define CAN_IDR_MB5 (0x1u << 5) /**< \brief (CAN_IDR) Mailbox 5 Interrupt Disable */
#define CAN_IDR_MB6 (0x1u << 6) /**< \brief (CAN_IDR) Mailbox 6 Interrupt Disable */
#define CAN_IDR_MB7 (0x1u << 7) /**< \brief (CAN_IDR) Mailbox 7 Interrupt Disable */
#define CAN_IDR_ERRA (0x1u << 16) /**< \brief (CAN_IDR) Error Active Mode Interrupt Disable */
#define CAN_IDR_WARN (0x1u << 17) /**< \brief (CAN_IDR) Warning Limit Interrupt Disable */
#define CAN_IDR_ERRP (0x1u << 18) /**< \brief (CAN_IDR) Error Passive Mode Interrupt Disable */
#define CAN_IDR_BOFF (0x1u << 19) /**< \brief (CAN_IDR) Bus Off Mode Interrupt Disable */
#define CAN_IDR_SLEEP (0x1u << 20) /**< \brief (CAN_IDR) Sleep Interrupt Disable */
#define CAN_IDR_WAKEUP (0x1u << 21) /**< \brief (CAN_IDR) Wakeup Interrupt Disable */
#define CAN_IDR_TOVF (0x1u << 22) /**< \brief (CAN_IDR) Timer Overflow Interrupt */
#define CAN_IDR_TSTP (0x1u << 23) /**< \brief (CAN_IDR) TimeStamp Interrupt Disable */
#define CAN_IDR_CERR (0x1u << 24) /**< \brief (CAN_IDR) CRC Error Interrupt Disable */
#define CAN_IDR_SERR (0x1u << 25) /**< \brief (CAN_IDR) Stuffing Error Interrupt Disable */
#define CAN_IDR_AERR (0x1u << 26) /**< \brief (CAN_IDR) Acknowledgment Error Interrupt Disable */
#define CAN_IDR_FERR (0x1u << 27) /**< \brief (CAN_IDR) Form Error Interrupt Disable */
#define CAN_IDR_BERR (0x1u << 28) /**< \brief (CAN_IDR) Bit Error Interrupt Disable */
/* -------- CAN_IMR : (CAN Offset: 0x000C) Interrupt Mask Register -------- */
#define CAN_IMR_MB0 (0x1u << 0) /**< \brief (CAN_IMR) Mailbox 0 Interrupt Mask */
#define CAN_IMR_MB1 (0x1u << 1) /**< \brief (CAN_IMR) Mailbox 1 Interrupt Mask */
#define CAN_IMR_MB2 (0x1u << 2) /**< \brief (CAN_IMR) Mailbox 2 Interrupt Mask */
#define CAN_IMR_MB3 (0x1u << 3) /**< \brief (CAN_IMR) Mailbox 3 Interrupt Mask */
#define CAN_IMR_MB4 (0x1u << 4) /**< \brief (CAN_IMR) Mailbox 4 Interrupt Mask */
#define CAN_IMR_MB5 (0x1u << 5) /**< \brief (CAN_IMR) Mailbox 5 Interrupt Mask */
#define CAN_IMR_MB6 (0x1u << 6) /**< \brief (CAN_IMR) Mailbox 6 Interrupt Mask */
#define CAN_IMR_MB7 (0x1u << 7) /**< \brief (CAN_IMR) Mailbox 7 Interrupt Mask */
#define CAN_IMR_ERRA (0x1u << 16) /**< \brief (CAN_IMR) Error Active Mode Interrupt Mask */
#define CAN_IMR_WARN (0x1u << 17) /**< \brief (CAN_IMR) Warning Limit Interrupt Mask */
#define CAN_IMR_ERRP (0x1u << 18) /**< \brief (CAN_IMR) Error Passive Mode Interrupt Mask */
#define CAN_IMR_BOFF (0x1u << 19) /**< \brief (CAN_IMR) Bus Off Mode Interrupt Mask */
#define CAN_IMR_SLEEP (0x1u << 20) /**< \brief (CAN_IMR) Sleep Interrupt Mask */
#define CAN_IMR_WAKEUP (0x1u << 21) /**< \brief (CAN_IMR) Wakeup Interrupt Mask */
#define CAN_IMR_TOVF (0x1u << 22) /**< \brief (CAN_IMR) Timer Overflow Interrupt Mask */
#define CAN_IMR_TSTP (0x1u << 23) /**< \brief (CAN_IMR) Timestamp Interrupt Mask */
#define CAN_IMR_CERR (0x1u << 24) /**< \brief (CAN_IMR) CRC Error Interrupt Mask */
#define CAN_IMR_SERR (0x1u << 25) /**< \brief (CAN_IMR) Stuffing Error Interrupt Mask */
#define CAN_IMR_AERR (0x1u << 26) /**< \brief (CAN_IMR) Acknowledgment Error Interrupt Mask */
#define CAN_IMR_FERR (0x1u << 27) /**< \brief (CAN_IMR) Form Error Interrupt Mask */
#define CAN_IMR_BERR (0x1u << 28) /**< \brief (CAN_IMR) Bit Error Interrupt Mask */
/* -------- CAN_SR : (CAN Offset: 0x0010) Status Register -------- */
#define CAN_SR_MB0 (0x1u << 0) /**< \brief (CAN_SR) Mailbox 0 Event */
#define CAN_SR_MB1 (0x1u << 1) /**< \brief (CAN_SR) Mailbox 1 Event */
#define CAN_SR_MB2 (0x1u << 2) /**< \brief (CAN_SR) Mailbox 2 Event */
#define CAN_SR_MB3 (0x1u << 3) /**< \brief (CAN_SR) Mailbox 3 Event */
#define CAN_SR_MB4 (0x1u << 4) /**< \brief (CAN_SR) Mailbox 4 Event */
#define CAN_SR_MB5 (0x1u << 5) /**< \brief (CAN_SR) Mailbox 5 Event */
#define CAN_SR_MB6 (0x1u << 6) /**< \brief (CAN_SR) Mailbox 6 Event */
#define CAN_SR_MB7 (0x1u << 7) /**< \brief (CAN_SR) Mailbox 7 Event */
#define CAN_SR_ERRA (0x1u << 16) /**< \brief (CAN_SR) Error Active Mode */
#define CAN_SR_WARN (0x1u << 17) /**< \brief (CAN_SR) Warning Limit */
#define CAN_SR_ERRP (0x1u << 18) /**< \brief (CAN_SR) Error Passive Mode */
#define CAN_SR_BOFF (0x1u << 19) /**< \brief (CAN_SR) Bus Off Mode */
#define CAN_SR_SLEEP (0x1u << 20) /**< \brief (CAN_SR) CAN controller in Low power Mode */
#define CAN_SR_WAKEUP (0x1u << 21) /**< \brief (CAN_SR) CAN controller is not in Low power Mode */
#define CAN_SR_TOVF (0x1u << 22) /**< \brief (CAN_SR) Timer Overflow */
#define CAN_SR_TSTP (0x1u << 23) /**< \brief (CAN_SR) */
#define CAN_SR_CERR (0x1u << 24) /**< \brief (CAN_SR) Mailbox CRC Error */
#define CAN_SR_SERR (0x1u << 25) /**< \brief (CAN_SR) Mailbox Stuffing Error */
#define CAN_SR_AERR (0x1u << 26) /**< \brief (CAN_SR) Acknowledgment Error */
#define CAN_SR_FERR (0x1u << 27) /**< \brief (CAN_SR) Form Error */
#define CAN_SR_BERR (0x1u << 28) /**< \brief (CAN_SR) Bit Error */
#define CAN_SR_RBSY (0x1u << 29) /**< \brief (CAN_SR) Receiver busy */
#define CAN_SR_TBSY (0x1u << 30) /**< \brief (CAN_SR) Transmitter busy */
#define CAN_SR_OVLSY (0x1u << 31) /**< \brief (CAN_SR) Overload busy */
/* -------- CAN_BR : (CAN Offset: 0x0014) Baudrate Register -------- */
#define CAN_BR_PHASE2_Pos 0
#define CAN_BR_PHASE2_Msk (0x7u << CAN_BR_PHASE2_Pos) /**< \brief (CAN_BR) Phase 2 segment */
#define CAN_BR_PHASE2(value) ((CAN_BR_PHASE2_Msk & ((value) << CAN_BR_PHASE2_Pos)))
#define CAN_BR_PHASE1_Pos 4
#define CAN_BR_PHASE1_Msk (0x7u << CAN_BR_PHASE1_Pos) /**< \brief (CAN_BR) Phase 1 segment */
#define CAN_BR_PHASE1(value) ((CAN_BR_PHASE1_Msk & ((value) << CAN_BR_PHASE1_Pos)))
#define CAN_BR_PROPAG_Pos 8
#define CAN_BR_PROPAG_Msk (0x7u << CAN_BR_PROPAG_Pos) /**< \brief (CAN_BR) Programming time segment */
#define CAN_BR_PROPAG(value) ((CAN_BR_PROPAG_Msk & ((value) << CAN_BR_PROPAG_Pos)))
#define CAN_BR_SJW_Pos 12
#define CAN_BR_SJW_Msk (0x3u << CAN_BR_SJW_Pos) /**< \brief (CAN_BR) Re-synchronization jump width */
#define CAN_BR_SJW(value) ((CAN_BR_SJW_Msk & ((value) << CAN_BR_SJW_Pos)))
#define CAN_BR_BRP_Pos 16
#define CAN_BR_BRP_Msk (0x7fu << CAN_BR_BRP_Pos) /**< \brief (CAN_BR) Baudrate Prescaler. */
#define CAN_BR_BRP(value) ((CAN_BR_BRP_Msk & ((value) << CAN_BR_BRP_Pos)))
#define CAN_BR_SMP (0x1u << 24) /**< \brief (CAN_BR) Sampling Mode */
#define CAN_BR_SMP_ONCE (0x0u << 24) /**< \brief (CAN_BR) The incoming bit stream is sampled once at sample point. */
#define CAN_BR_SMP_THREE (0x1u << 24) /**< \brief (CAN_BR) The incoming bit stream is sampled three times with a period of a MCK clock period, centered on sample point. */
/* -------- CAN_TIM : (CAN Offset: 0x0018) Timer Register -------- */
#define CAN_TIM_TIMER_Pos 0
#define CAN_TIM_TIMER_Msk (0xffffu << CAN_TIM_TIMER_Pos) /**< \brief (CAN_TIM) Timer */
/* -------- CAN_TIMESTP : (CAN Offset: 0x001C) Timestamp Register -------- */
#define CAN_TIMESTP_MTIMESTAMP_Pos 0
#define CAN_TIMESTP_MTIMESTAMP_Msk (0xffffu << CAN_TIMESTP_MTIMESTAMP_Pos) /**< \brief (CAN_TIMESTP) Timestamp */
/* -------- CAN_ECR : (CAN Offset: 0x0020) Error Counter Register -------- */
#define CAN_ECR_REC_Pos 0
#define CAN_ECR_REC_Msk (0xffu << CAN_ECR_REC_Pos) /**< \brief (CAN_ECR) Receive Error Counter */
#define CAN_ECR_TEC_Pos 16
#define CAN_ECR_TEC_Msk (0xffu << CAN_ECR_TEC_Pos) /**< \brief (CAN_ECR) Transmit Error Counter */
/* -------- CAN_TCR : (CAN Offset: 0x0024) Transfer Command Register -------- */
#define CAN_TCR_MB0 (0x1u << 0) /**< \brief (CAN_TCR) Transfer Request for Mailbox 0 */
#define CAN_TCR_MB1 (0x1u << 1) /**< \brief (CAN_TCR) Transfer Request for Mailbox 1 */
#define CAN_TCR_MB2 (0x1u << 2) /**< \brief (CAN_TCR) Transfer Request for Mailbox 2 */
#define CAN_TCR_MB3 (0x1u << 3) /**< \brief (CAN_TCR) Transfer Request for Mailbox 3 */
#define CAN_TCR_MB4 (0x1u << 4) /**< \brief (CAN_TCR) Transfer Request for Mailbox 4 */
#define CAN_TCR_MB5 (0x1u << 5) /**< \brief (CAN_TCR) Transfer Request for Mailbox 5 */
#define CAN_TCR_MB6 (0x1u << 6) /**< \brief (CAN_TCR) Transfer Request for Mailbox 6 */
#define CAN_TCR_MB7 (0x1u << 7) /**< \brief (CAN_TCR) Transfer Request for Mailbox 7 */
#define CAN_TCR_TIMRST (0x1u << 31) /**< \brief (CAN_TCR) Timer Reset */
/* -------- CAN_ACR : (CAN Offset: 0x0028) Abort Command Register -------- */
#define CAN_ACR_MB0 (0x1u << 0) /**< \brief (CAN_ACR) Abort Request for Mailbox 0 */
#define CAN_ACR_MB1 (0x1u << 1) /**< \brief (CAN_ACR) Abort Request for Mailbox 1 */
#define CAN_ACR_MB2 (0x1u << 2) /**< \brief (CAN_ACR) Abort Request for Mailbox 2 */
#define CAN_ACR_MB3 (0x1u << 3) /**< \brief (CAN_ACR) Abort Request for Mailbox 3 */
#define CAN_ACR_MB4 (0x1u << 4) /**< \brief (CAN_ACR) Abort Request for Mailbox 4 */
#define CAN_ACR_MB5 (0x1u << 5) /**< \brief (CAN_ACR) Abort Request for Mailbox 5 */
#define CAN_ACR_MB6 (0x1u << 6) /**< \brief (CAN_ACR) Abort Request for Mailbox 6 */
#define CAN_ACR_MB7 (0x1u << 7) /**< \brief (CAN_ACR) Abort Request for Mailbox 7 */
/* -------- CAN_WPMR : (CAN Offset: 0x00E4) Write Protect Mode Register -------- */
#define CAN_WPMR_WPEN (0x1u << 0) /**< \brief (CAN_WPMR) Write Protection Enable */
#define CAN_WPMR_WPKEY_Pos 8
#define CAN_WPMR_WPKEY_Msk (0xffffffu << CAN_WPMR_WPKEY_Pos) /**< \brief (CAN_WPMR) SPI Write Protection Key Password */
#define CAN_WPMR_WPKEY(value) ((CAN_WPMR_WPKEY_Msk & ((value) << CAN_WPMR_WPKEY_Pos)))
/* -------- CAN_WPSR : (CAN Offset: 0x00E8) Write Protect Status Register -------- */
#define CAN_WPSR_WPVS (0x1u << 0) /**< \brief (CAN_WPSR) Write Protection Violation Status */
#define CAN_WPSR_WPVSRC_Pos 8
#define CAN_WPSR_WPVSRC_Msk (0xffu << CAN_WPSR_WPVSRC_Pos) /**< \brief (CAN_WPSR) Write Protection Violation Source */
/* -------- CAN_MMR : (CAN Offset: N/A) Mailbox Mode Register -------- */
#define CAN_MMR_MTIMEMARK_Pos 0
#define CAN_MMR_MTIMEMARK_Msk (0xffffu << CAN_MMR_MTIMEMARK_Pos) /**< \brief (CAN_MMR) Mailbox Timemark */
#define CAN_MMR_MTIMEMARK(value) ((CAN_MMR_MTIMEMARK_Msk & ((value) << CAN_MMR_MTIMEMARK_Pos)))
#define CAN_MMR_PRIOR_Pos 16
#define CAN_MMR_PRIOR_Msk (0xfu << CAN_MMR_PRIOR_Pos) /**< \brief (CAN_MMR) Mailbox Priority */
#define CAN_MMR_PRIOR(value) ((CAN_MMR_PRIOR_Msk & ((value) << CAN_MMR_PRIOR_Pos)))
#define CAN_MMR_MOT_Pos 24
#define CAN_MMR_MOT_Msk (0x7u << CAN_MMR_MOT_Pos) /**< \brief (CAN_MMR) Mailbox Object Type */
#define CAN_MMR_MOT_MB_DISABLED (0x0u << 24) /**< \brief (CAN_MMR) Mailbox is disabled. This prevents receiving or transmitting any messages with this mailbox. */
#define CAN_MMR_MOT_MB_RX (0x1u << 24) /**< \brief (CAN_MMR) Reception Mailbox. Mailbox is configured for reception. If a message is received while the mailbox data register is full, it is discarded. */
#define CAN_MMR_MOT_MB_RX_OVERWRITE (0x2u << 24) /**< \brief (CAN_MMR) Reception mailbox with overwrite. Mailbox is configured for reception. If a message is received while the mailbox is full, it overwrites the previous message. */
#define CAN_MMR_MOT_MB_TX (0x3u << 24) /**< \brief (CAN_MMR) Transmit mailbox. Mailbox is configured for transmission. */
#define CAN_MMR_MOT_MB_CONSUMER (0x4u << 24) /**< \brief (CAN_MMR) Consumer Mailbox. Mailbox is configured in reception but behaves as a Transmit Mailbox, i.e., it sends a remote frame and waits for an answer. */
#define CAN_MMR_MOT_MB_PRODUCER (0x5u << 24) /**< \brief (CAN_MMR) Producer Mailbox. Mailbox is configured in transmission but also behaves like a reception mailbox, i.e., it waits to receive a Remote Frame before sending its contents. */
/* -------- CAN_MAM : (CAN Offset: N/A) Mailbox Acceptance Mask Register -------- */
#define CAN_MAM_MIDvB_Pos 0
#define CAN_MAM_MIDvB_Msk (0x3ffffu << CAN_MAM_MIDvB_Pos) /**< \brief (CAN_MAM) Complementary bits for identifier in extended frame mode */
#define CAN_MAM_MIDvB(value) ((CAN_MAM_MIDvB_Msk & ((value) << CAN_MAM_MIDvB_Pos)))
#define CAN_MAM_MIDvA_Pos 18
#define CAN_MAM_MIDvA_Msk (0x7ffu << CAN_MAM_MIDvA_Pos) /**< \brief (CAN_MAM) Identifier for standard frame mode */
#define CAN_MAM_MIDvA(value) ((CAN_MAM_MIDvA_Msk & ((value) << CAN_MAM_MIDvA_Pos)))
#define CAN_MAM_MIDE (0x1u << 29) /**< \brief (CAN_MAM) Identifier Version */
/* -------- CAN_MID : (CAN Offset: N/A) Mailbox ID Register -------- */
#define CAN_MID_MIDvB_Pos 0
#define CAN_MID_MIDvB_Msk (0x3ffffu << CAN_MID_MIDvB_Pos) /**< \brief (CAN_MID) Complementary bits for identifier in extended frame mode */
#define CAN_MID_MIDvB(value) ((CAN_MID_MIDvB_Msk & ((value) << CAN_MID_MIDvB_Pos)))
#define CAN_MID_MIDvA_Pos 18
#define CAN_MID_MIDvA_Msk (0x7ffu << CAN_MID_MIDvA_Pos) /**< \brief (CAN_MID) Identifier for standard frame mode */
#define CAN_MID_MIDvA(value) ((CAN_MID_MIDvA_Msk & ((value) << CAN_MID_MIDvA_Pos)))
#define CAN_MID_MIDE (0x1u << 29) /**< \brief (CAN_MID) Identifier Version */
/* -------- CAN_MFID : (CAN Offset: N/A) Mailbox Family ID Register -------- */
#define CAN_MFID_MFID_Pos 0
#define CAN_MFID_MFID_Msk (0x1fffffffu << CAN_MFID_MFID_Pos) /**< \brief (CAN_MFID) Family ID */
/* -------- CAN_MSR : (CAN Offset: N/A) Mailbox Status Register -------- */
#define CAN_MSR_MTIMESTAMP_Pos 0
#define CAN_MSR_MTIMESTAMP_Msk (0xffffu << CAN_MSR_MTIMESTAMP_Pos) /**< \brief (CAN_MSR) Timer value */
#define CAN_MSR_MDLC_Pos 16
#define CAN_MSR_MDLC_Msk (0xfu << CAN_MSR_MDLC_Pos) /**< \brief (CAN_MSR) Mailbox Data Length Code */
#define CAN_MSR_MRTR (0x1u << 20) /**< \brief (CAN_MSR) Mailbox Remote Transmission Request */
#define CAN_MSR_MABT (0x1u << 22) /**< \brief (CAN_MSR) Mailbox Message Abort */
#define CAN_MSR_MRDY (0x1u << 23) /**< \brief (CAN_MSR) Mailbox Ready */
#define CAN_MSR_MMI (0x1u << 24) /**< \brief (CAN_MSR) Mailbox Message Ignored */
/* -------- CAN_MDL : (CAN Offset: N/A) Mailbox Data Low Register -------- */
#define CAN_MDL_MDL_Pos 0
#define CAN_MDL_MDL_Msk (0xffffffffu << CAN_MDL_MDL_Pos) /**< \brief (CAN_MDL) Message Data Low Value */
#define CAN_MDL_MDL(value) ((CAN_MDL_MDL_Msk & ((value) << CAN_MDL_MDL_Pos)))
/* -------- CAN_MDH : (CAN Offset: N/A) Mailbox Data High Register -------- */
#define CAN_MDH_MDH_Pos 0
#define CAN_MDH_MDH_Msk (0xffffffffu << CAN_MDH_MDH_Pos) /**< \brief (CAN_MDH) Message Data High Value */
#define CAN_MDH_MDH(value) ((CAN_MDH_MDH_Msk & ((value) << CAN_MDH_MDH_Pos)))
/* -------- CAN_MCR : (CAN Offset: N/A) Mailbox Control Register -------- */
#define CAN_MCR_MDLC_Pos 16
#define CAN_MCR_MDLC_Msk (0xfu << CAN_MCR_MDLC_Pos) /**< \brief (CAN_MCR) Mailbox Data Length Code */
#define CAN_MCR_MDLC(value) ((CAN_MCR_MDLC_Msk & ((value) << CAN_MCR_MDLC_Pos)))
#define CAN_MCR_MRTR (0x1u << 20) /**< \brief (CAN_MCR) Mailbox Remote Transmission Request */
#define CAN_MCR_MACR (0x1u << 22) /**< \brief (CAN_MCR) Abort Request for Mailbox x */
#define CAN_MCR_MTCR (0x1u << 23) /**< \brief (CAN_MCR) Mailbox Transfer Command */
/*@}*/
#endif /* _SAM3XA_CAN_COMPONENT_ */

View File

@@ -0,0 +1,159 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2012, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _SAM3XA_CHIPID_COMPONENT_
#define _SAM3XA_CHIPID_COMPONENT_
/* ============================================================================= */
/** SOFTWARE API DEFINITION FOR Chip Identifier */
/* ============================================================================= */
/** \addtogroup SAM3XA_CHIPID Chip Identifier */
/*@{*/
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
/** \brief Chipid hardware registers */
typedef struct {
RoReg CHIPID_CIDR; /**< \brief (Chipid Offset: 0x0) Chip ID Register */
RoReg CHIPID_EXID; /**< \brief (Chipid Offset: 0x4) Chip ID Extension Register */
} Chipid;
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
/* -------- CHIPID_CIDR : (CHIPID Offset: 0x0) Chip ID Register -------- */
#define CHIPID_CIDR_VERSION_Pos 0
#define CHIPID_CIDR_VERSION_Msk (0x1fu << CHIPID_CIDR_VERSION_Pos) /**< \brief (CHIPID_CIDR) Version of the Device */
#define CHIPID_CIDR_EPROC_Pos 5
#define CHIPID_CIDR_EPROC_Msk (0x7u << CHIPID_CIDR_EPROC_Pos) /**< \brief (CHIPID_CIDR) Embedded Processor */
#define CHIPID_CIDR_EPROC_ARM946ES (0x1u << 5) /**< \brief (CHIPID_CIDR) ARM946ES */
#define CHIPID_CIDR_EPROC_ARM7TDMI (0x2u << 5) /**< \brief (CHIPID_CIDR) ARM7TDMI */
#define CHIPID_CIDR_EPROC_CM3 (0x3u << 5) /**< \brief (CHIPID_CIDR) Cortex-M3 */
#define CHIPID_CIDR_EPROC_ARM920T (0x4u << 5) /**< \brief (CHIPID_CIDR) ARM920T */
#define CHIPID_CIDR_EPROC_ARM926EJS (0x5u << 5) /**< \brief (CHIPID_CIDR) ARM926EJS */
#define CHIPID_CIDR_EPROC_CA5 (0x6u << 5) /**< \brief (CHIPID_CIDR) Cortex-A5 */
#define CHIPID_CIDR_EPROC_CM4 (0x7u << 5) /**< \brief (CHIPID_CIDR) Cortex-M4 */
#define CHIPID_CIDR_NVPSIZ_Pos 8
#define CHIPID_CIDR_NVPSIZ_Msk (0xfu << CHIPID_CIDR_NVPSIZ_Pos) /**< \brief (CHIPID_CIDR) Nonvolatile Program Memory Size */
#define CHIPID_CIDR_NVPSIZ_NONE (0x0u << 8) /**< \brief (CHIPID_CIDR) None */
#define CHIPID_CIDR_NVPSIZ_8K (0x1u << 8) /**< \brief (CHIPID_CIDR) 8K bytes */
#define CHIPID_CIDR_NVPSIZ_16K (0x2u << 8) /**< \brief (CHIPID_CIDR) 16K bytes */
#define CHIPID_CIDR_NVPSIZ_32K (0x3u << 8) /**< \brief (CHIPID_CIDR) 32K bytes */
#define CHIPID_CIDR_NVPSIZ_64K (0x5u << 8) /**< \brief (CHIPID_CIDR) 64K bytes */
#define CHIPID_CIDR_NVPSIZ_128K (0x7u << 8) /**< \brief (CHIPID_CIDR) 128K bytes */
#define CHIPID_CIDR_NVPSIZ_256K (0x9u << 8) /**< \brief (CHIPID_CIDR) 256K bytes */
#define CHIPID_CIDR_NVPSIZ_512K (0xAu << 8) /**< \brief (CHIPID_CIDR) 512K bytes */
#define CHIPID_CIDR_NVPSIZ_1024K (0xCu << 8) /**< \brief (CHIPID_CIDR) 1024K bytes */
#define CHIPID_CIDR_NVPSIZ_2048K (0xEu << 8) /**< \brief (CHIPID_CIDR) 2048K bytes */
#define CHIPID_CIDR_NVPSIZ2_Pos 12
#define CHIPID_CIDR_NVPSIZ2_Msk (0xfu << CHIPID_CIDR_NVPSIZ2_Pos) /**< \brief (CHIPID_CIDR) Second Nonvolatile Program Memory Size */
#define CHIPID_CIDR_NVPSIZ2_NONE (0x0u << 12) /**< \brief (CHIPID_CIDR) None */
#define CHIPID_CIDR_NVPSIZ2_8K (0x1u << 12) /**< \brief (CHIPID_CIDR) 8K bytes */
#define CHIPID_CIDR_NVPSIZ2_16K (0x2u << 12) /**< \brief (CHIPID_CIDR) 16K bytes */
#define CHIPID_CIDR_NVPSIZ2_32K (0x3u << 12) /**< \brief (CHIPID_CIDR) 32K bytes */
#define CHIPID_CIDR_NVPSIZ2_64K (0x5u << 12) /**< \brief (CHIPID_CIDR) 64K bytes */
#define CHIPID_CIDR_NVPSIZ2_128K (0x7u << 12) /**< \brief (CHIPID_CIDR) 128K bytes */
#define CHIPID_CIDR_NVPSIZ2_256K (0x9u << 12) /**< \brief (CHIPID_CIDR) 256K bytes */
#define CHIPID_CIDR_NVPSIZ2_512K (0xAu << 12) /**< \brief (CHIPID_CIDR) 512K bytes */
#define CHIPID_CIDR_NVPSIZ2_1024K (0xCu << 12) /**< \brief (CHIPID_CIDR) 1024K bytes */
#define CHIPID_CIDR_NVPSIZ2_2048K (0xEu << 12) /**< \brief (CHIPID_CIDR) 2048K bytes */
#define CHIPID_CIDR_SRAMSIZ_Pos 16
#define CHIPID_CIDR_SRAMSIZ_Msk (0xfu << CHIPID_CIDR_SRAMSIZ_Pos) /**< \brief (CHIPID_CIDR) Internal SRAM Size */
#define CHIPID_CIDR_SRAMSIZ_48K (0x0u << 16) /**< \brief (CHIPID_CIDR) 48K bytes */
#define CHIPID_CIDR_SRAMSIZ_1K (0x1u << 16) /**< \brief (CHIPID_CIDR) 1K bytes */
#define CHIPID_CIDR_SRAMSIZ_2K (0x2u << 16) /**< \brief (CHIPID_CIDR) 2K bytes */
#define CHIPID_CIDR_SRAMSIZ_6K (0x3u << 16) /**< \brief (CHIPID_CIDR) 6K bytes */
#define CHIPID_CIDR_SRAMSIZ_24K (0x4u << 16) /**< \brief (CHIPID_CIDR) 24K bytes */
#define CHIPID_CIDR_SRAMSIZ_4K (0x5u << 16) /**< \brief (CHIPID_CIDR) 4K bytes */
#define CHIPID_CIDR_SRAMSIZ_80K (0x6u << 16) /**< \brief (CHIPID_CIDR) 80K bytes */
#define CHIPID_CIDR_SRAMSIZ_160K (0x7u << 16) /**< \brief (CHIPID_CIDR) 160K bytes */
#define CHIPID_CIDR_SRAMSIZ_8K (0x8u << 16) /**< \brief (CHIPID_CIDR) 8K bytes */
#define CHIPID_CIDR_SRAMSIZ_16K (0x9u << 16) /**< \brief (CHIPID_CIDR) 16K bytes */
#define CHIPID_CIDR_SRAMSIZ_32K (0xAu << 16) /**< \brief (CHIPID_CIDR) 32K bytes */
#define CHIPID_CIDR_SRAMSIZ_64K (0xBu << 16) /**< \brief (CHIPID_CIDR) 64K bytes */
#define CHIPID_CIDR_SRAMSIZ_128K (0xCu << 16) /**< \brief (CHIPID_CIDR) 128K bytes */
#define CHIPID_CIDR_SRAMSIZ_256K (0xDu << 16) /**< \brief (CHIPID_CIDR) 256K bytes */
#define CHIPID_CIDR_SRAMSIZ_96K (0xEu << 16) /**< \brief (CHIPID_CIDR) 96K bytes */
#define CHIPID_CIDR_SRAMSIZ_512K (0xFu << 16) /**< \brief (CHIPID_CIDR) 512K bytes */
#define CHIPID_CIDR_ARCH_Pos 20
#define CHIPID_CIDR_ARCH_Msk (0xffu << CHIPID_CIDR_ARCH_Pos) /**< \brief (CHIPID_CIDR) Architecture Identifier */
#define CHIPID_CIDR_ARCH_AT91SAM9xx (0x19u << 20) /**< \brief (CHIPID_CIDR) AT91SAM9xx Series */
#define CHIPID_CIDR_ARCH_AT91SAM9XExx (0x29u << 20) /**< \brief (CHIPID_CIDR) AT91SAM9XExx Series */
#define CHIPID_CIDR_ARCH_AT91x34 (0x34u << 20) /**< \brief (CHIPID_CIDR) AT91x34 Series */
#define CHIPID_CIDR_ARCH_CAP7 (0x37u << 20) /**< \brief (CHIPID_CIDR) CAP7 Series */
#define CHIPID_CIDR_ARCH_CAP9 (0x39u << 20) /**< \brief (CHIPID_CIDR) CAP9 Series */
#define CHIPID_CIDR_ARCH_CAP11 (0x3Bu << 20) /**< \brief (CHIPID_CIDR) CAP11 Series */
#define CHIPID_CIDR_ARCH_AT91x40 (0x40u << 20) /**< \brief (CHIPID_CIDR) AT91x40 Series */
#define CHIPID_CIDR_ARCH_AT91x42 (0x42u << 20) /**< \brief (CHIPID_CIDR) AT91x42 Series */
#define CHIPID_CIDR_ARCH_AT91x55 (0x55u << 20) /**< \brief (CHIPID_CIDR) AT91x55 Series */
#define CHIPID_CIDR_ARCH_AT91SAM7Axx (0x60u << 20) /**< \brief (CHIPID_CIDR) AT91SAM7Axx Series */
#define CHIPID_CIDR_ARCH_AT91SAM7AQxx (0x61u << 20) /**< \brief (CHIPID_CIDR) AT91SAM7AQxx Series */
#define CHIPID_CIDR_ARCH_AT91x63 (0x63u << 20) /**< \brief (CHIPID_CIDR) AT91x63 Series */
#define CHIPID_CIDR_ARCH_AT91SAM7Sxx (0x70u << 20) /**< \brief (CHIPID_CIDR) AT91SAM7Sxx Series */
#define CHIPID_CIDR_ARCH_AT91SAM7XCxx (0x71u << 20) /**< \brief (CHIPID_CIDR) AT91SAM7XCxx Series */
#define CHIPID_CIDR_ARCH_AT91SAM7SExx (0x72u << 20) /**< \brief (CHIPID_CIDR) AT91SAM7SExx Series */
#define CHIPID_CIDR_ARCH_AT91SAM7Lxx (0x73u << 20) /**< \brief (CHIPID_CIDR) AT91SAM7Lxx Series */
#define CHIPID_CIDR_ARCH_AT91SAM7Xxx (0x75u << 20) /**< \brief (CHIPID_CIDR) AT91SAM7Xxx Series */
#define CHIPID_CIDR_ARCH_AT91SAM7SLxx (0x76u << 20) /**< \brief (CHIPID_CIDR) AT91SAM7SLxx Series */
#define CHIPID_CIDR_ARCH_SAM3UxC (0x80u << 20) /**< \brief (CHIPID_CIDR) SAM3UxC Series (100-pin version) */
#define CHIPID_CIDR_ARCH_SAM3UxE (0x81u << 20) /**< \brief (CHIPID_CIDR) SAM3UxE Series (144-pin version) */
#define CHIPID_CIDR_ARCH_SAM3AxC (0x83u << 20) /**< \brief (CHIPID_CIDR) SAM3AxC Series (100-pin version) */
#define CHIPID_CIDR_ARCH_SAM4AxC (0x83u << 20) /**< \brief (CHIPID_CIDR) SAM4AxC Series (100-pin version) */
#define CHIPID_CIDR_ARCH_SAM3XxC (0x84u << 20) /**< \brief (CHIPID_CIDR) SAM3XxC Series (100-pin version) */
#define CHIPID_CIDR_ARCH_SAM4XxC (0x84u << 20) /**< \brief (CHIPID_CIDR) SAM4XxC Series (100-pin version) */
#define CHIPID_CIDR_ARCH_SAM3XxE (0x85u << 20) /**< \brief (CHIPID_CIDR) SAM3XxE Series (144-pin version) */
#define CHIPID_CIDR_ARCH_SAM4XxE (0x85u << 20) /**< \brief (CHIPID_CIDR) SAM4XxE Series (144-pin version) */
#define CHIPID_CIDR_ARCH_SAM3XxG (0x86u << 20) /**< \brief (CHIPID_CIDR) SAM3XxG Series (208/217-pin version) */
#define CHIPID_CIDR_ARCH_SAM4XxG (0x86u << 20) /**< \brief (CHIPID_CIDR) SAM4XxG Series (208/217-pin version) */
#define CHIPID_CIDR_ARCH_SAM3SxA (0x88u << 20) /**< \brief (CHIPID_CIDR) SAM3SxASeries (48-pin version) */
#define CHIPID_CIDR_ARCH_SAM4SxA (0x88u << 20) /**< \brief (CHIPID_CIDR) SAM4SxA Series (48-pin version) */
#define CHIPID_CIDR_ARCH_SAM3SxB (0x89u << 20) /**< \brief (CHIPID_CIDR) SAM3SxB Series (64-pin version) */
#define CHIPID_CIDR_ARCH_SAM4SxB (0x89u << 20) /**< \brief (CHIPID_CIDR) SAM4SxB Series (64-pin version) */
#define CHIPID_CIDR_ARCH_SAM3SxC (0x8Au << 20) /**< \brief (CHIPID_CIDR) SAM3SxC Series (100-pin version) */
#define CHIPID_CIDR_ARCH_SAM4SxC (0x8Au << 20) /**< \brief (CHIPID_CIDR) SAM4SxC Series (100-pin version) */
#define CHIPID_CIDR_ARCH_AT91x92 (0x92u << 20) /**< \brief (CHIPID_CIDR) AT91x92 Series */
#define CHIPID_CIDR_ARCH_SAM3NxA (0x93u << 20) /**< \brief (CHIPID_CIDR) SAM3NxA Series (48-pin version) */
#define CHIPID_CIDR_ARCH_SAM3NxB (0x94u << 20) /**< \brief (CHIPID_CIDR) SAM3NxB Series (64-pin version) */
#define CHIPID_CIDR_ARCH_SAM3NxC (0x95u << 20) /**< \brief (CHIPID_CIDR) SAM3NxC Series (100-pin version) */
#define CHIPID_CIDR_ARCH_SAM3SDxB (0x99u << 20) /**< \brief (CHIPID_CIDR) SAM3SDxB Series (64-pin version) */
#define CHIPID_CIDR_ARCH_SAM3SDxC (0x9Au << 20) /**< \brief (CHIPID_CIDR) SAM3SDxC Series (100-pin version) */
#define CHIPID_CIDR_ARCH_SAM5A (0xA5u << 20) /**< \brief (CHIPID_CIDR) SAM5A */
#define CHIPID_CIDR_ARCH_AT75Cxx (0xF0u << 20) /**< \brief (CHIPID_CIDR) AT75Cxx Series */
#define CHIPID_CIDR_NVPTYP_Pos 28
#define CHIPID_CIDR_NVPTYP_Msk (0x7u << CHIPID_CIDR_NVPTYP_Pos) /**< \brief (CHIPID_CIDR) Nonvolatile Program Memory Type */
#define CHIPID_CIDR_NVPTYP_ROM (0x0u << 28) /**< \brief (CHIPID_CIDR) ROM */
#define CHIPID_CIDR_NVPTYP_ROMLESS (0x1u << 28) /**< \brief (CHIPID_CIDR) ROMless or on-chip Flash */
#define CHIPID_CIDR_NVPTYP_FLASH (0x2u << 28) /**< \brief (CHIPID_CIDR) Embedded Flash Memory */
#define CHIPID_CIDR_NVPTYP_ROM_FLASH (0x3u << 28) /**< \brief (CHIPID_CIDR) ROM and Embedded Flash MemoryNVPSIZ is ROM size NVPSIZ2 is Flash size */
#define CHIPID_CIDR_NVPTYP_SRAM (0x4u << 28) /**< \brief (CHIPID_CIDR) SRAM emulating ROM */
#define CHIPID_CIDR_EXT (0x1u << 31) /**< \brief (CHIPID_CIDR) Extension Flag */
/* -------- CHIPID_EXID : (CHIPID Offset: 0x4) Chip ID Extension Register -------- */
#define CHIPID_EXID_EXID_Pos 0
#define CHIPID_EXID_EXID_Msk (0xffffffffu << CHIPID_EXID_EXID_Pos) /**< \brief (CHIPID_EXID) Chip ID Extension */
/*@}*/
#endif /* _SAM3XA_CHIPID_COMPONENT_ */

View File

@@ -0,0 +1,210 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2012, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _SAM3XA_DACC_COMPONENT_
#define _SAM3XA_DACC_COMPONENT_
/* ============================================================================= */
/** SOFTWARE API DEFINITION FOR Digital-to-Analog Converter Controller */
/* ============================================================================= */
/** \addtogroup SAM3XA_DACC Digital-to-Analog Converter Controller */
/*@{*/
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
/** \brief Dacc hardware registers */
typedef struct {
WoReg DACC_CR; /**< \brief (Dacc Offset: 0x00) Control Register */
RwReg DACC_MR; /**< \brief (Dacc Offset: 0x04) Mode Register */
RoReg Reserved1[2];
WoReg DACC_CHER; /**< \brief (Dacc Offset: 0x10) Channel Enable Register */
WoReg DACC_CHDR; /**< \brief (Dacc Offset: 0x14) Channel Disable Register */
RoReg DACC_CHSR; /**< \brief (Dacc Offset: 0x18) Channel Status Register */
RoReg Reserved2[1];
WoReg DACC_CDR; /**< \brief (Dacc Offset: 0x20) Conversion Data Register */
WoReg DACC_IER; /**< \brief (Dacc Offset: 0x24) Interrupt Enable Register */
WoReg DACC_IDR; /**< \brief (Dacc Offset: 0x28) Interrupt Disable Register */
RoReg DACC_IMR; /**< \brief (Dacc Offset: 0x2C) Interrupt Mask Register */
RoReg DACC_ISR; /**< \brief (Dacc Offset: 0x30) Interrupt Status Register */
RoReg Reserved3[24];
RwReg DACC_ACR; /**< \brief (Dacc Offset: 0x94) Analog Current Register */
RoReg Reserved4[19];
RwReg DACC_WPMR; /**< \brief (Dacc Offset: 0xE4) Write Protect Mode register */
RoReg DACC_WPSR; /**< \brief (Dacc Offset: 0xE8) Write Protect Status register */
RoReg Reserved5[7];
RwReg DACC_TPR; /**< \brief (Dacc Offset: 0x108) Transmit Pointer Register */
RwReg DACC_TCR; /**< \brief (Dacc Offset: 0x10C) Transmit Counter Register */
RoReg Reserved6[2];
RwReg DACC_TNPR; /**< \brief (Dacc Offset: 0x118) Transmit Next Pointer Register */
RwReg DACC_TNCR; /**< \brief (Dacc Offset: 0x11C) Transmit Next Counter Register */
WoReg DACC_PTCR; /**< \brief (Dacc Offset: 0x120) Transfer Control Register */
RoReg DACC_PTSR; /**< \brief (Dacc Offset: 0x124) Transfer Status Register */
} Dacc;
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
/* -------- DACC_CR : (DACC Offset: 0x00) Control Register -------- */
#define DACC_CR_SWRST (0x1u << 0) /**< \brief (DACC_CR) Software Reset */
/* -------- DACC_MR : (DACC Offset: 0x04) Mode Register -------- */
#define DACC_MR_TRGEN (0x1u << 0) /**< \brief (DACC_MR) Trigger Enable */
#define DACC_MR_TRGEN_DIS (0x0u << 0) /**< \brief (DACC_MR) External trigger mode disabled. DACC in free running mode. */
#define DACC_MR_TRGEN_EN (0x1u << 0) /**< \brief (DACC_MR) External trigger mode enabled. */
#define DACC_MR_TRGSEL_Pos 1
#define DACC_MR_TRGSEL_Msk (0x7u << DACC_MR_TRGSEL_Pos) /**< \brief (DACC_MR) Trigger Selection */
#define DACC_MR_TRGSEL(value) ((DACC_MR_TRGSEL_Msk & ((value) << DACC_MR_TRGSEL_Pos)))
#define DACC_MR_WORD (0x1u << 4) /**< \brief (DACC_MR) Word Transfer */
#define DACC_MR_WORD_HALF (0x0u << 4) /**< \brief (DACC_MR) Half-Word transfer */
#define DACC_MR_WORD_WORD (0x1u << 4) /**< \brief (DACC_MR) Word Transfer */
#define DACC_MR_SLEEP (0x1u << 5) /**< \brief (DACC_MR) Sleep Mode */
#define DACC_MR_FASTWKUP (0x1u << 6) /**< \brief (DACC_MR) Fast Wake up Mode */
#define DACC_MR_REFRESH_Pos 8
#define DACC_MR_REFRESH_Msk (0xffu << DACC_MR_REFRESH_Pos) /**< \brief (DACC_MR) Refresh Period */
#define DACC_MR_REFRESH(value) ((DACC_MR_REFRESH_Msk & ((value) << DACC_MR_REFRESH_Pos)))
#define DACC_MR_USER_SEL_Pos 16
#define DACC_MR_USER_SEL_Msk (0x3u << DACC_MR_USER_SEL_Pos) /**< \brief (DACC_MR) User Channel Selection */
#define DACC_MR_USER_SEL_CHANNEL0 (0x0u << 16) /**< \brief (DACC_MR) Channel 0 */
#define DACC_MR_USER_SEL_CHANNEL1 (0x1u << 16) /**< \brief (DACC_MR) Channel 1 */
#define DACC_MR_TAG (0x1u << 20) /**< \brief (DACC_MR) Tag Selection Mode */
#define DACC_MR_TAG_DIS (0x0u << 20) /**< \brief (DACC_MR) Tag selection mode disabled. Using USER_SEL to select the channel for the conversion. */
#define DACC_MR_TAG_EN (0x1u << 20) /**< \brief (DACC_MR) Tag selection mode enabled */
#define DACC_MR_MAXS (0x1u << 21) /**< \brief (DACC_MR) Max Speed Mode */
#define DACC_MR_MAXS_NORMAL (0x0u << 21) /**< \brief (DACC_MR) Normal Mode */
#define DACC_MR_MAXS_MAXIMUM (0x1u << 21) /**< \brief (DACC_MR) Max Speed Mode enabled */
#define DACC_MR_STARTUP_Pos 24
#define DACC_MR_STARTUP_Msk (0x3fu << DACC_MR_STARTUP_Pos) /**< \brief (DACC_MR) Startup Time Selection */
#define DACC_MR_STARTUP_0 (0x0u << 24) /**< \brief (DACC_MR) 0 periods of DACClock */
#define DACC_MR_STARTUP_8 (0x1u << 24) /**< \brief (DACC_MR) 8 periods of DACClock */
#define DACC_MR_STARTUP_16 (0x2u << 24) /**< \brief (DACC_MR) 16 periods of DACClock */
#define DACC_MR_STARTUP_24 (0x3u << 24) /**< \brief (DACC_MR) 24 periods of DACClock */
#define DACC_MR_STARTUP_64 (0x4u << 24) /**< \brief (DACC_MR) 64 periods of DACClock */
#define DACC_MR_STARTUP_80 (0x5u << 24) /**< \brief (DACC_MR) 80 periods of DACClock */
#define DACC_MR_STARTUP_96 (0x6u << 24) /**< \brief (DACC_MR) 96 periods of DACClock */
#define DACC_MR_STARTUP_112 (0x7u << 24) /**< \brief (DACC_MR) 112 periods of DACClock */
#define DACC_MR_STARTUP_512 (0x8u << 24) /**< \brief (DACC_MR) 512 periods of DACClock */
#define DACC_MR_STARTUP_576 (0x9u << 24) /**< \brief (DACC_MR) 576 periods of DACClock */
#define DACC_MR_STARTUP_640 (0xAu << 24) /**< \brief (DACC_MR) 640 periods of DACClock */
#define DACC_MR_STARTUP_704 (0xBu << 24) /**< \brief (DACC_MR) 704 periods of DACClock */
#define DACC_MR_STARTUP_768 (0xCu << 24) /**< \brief (DACC_MR) 768 periods of DACClock */
#define DACC_MR_STARTUP_832 (0xDu << 24) /**< \brief (DACC_MR) 832 periods of DACClock */
#define DACC_MR_STARTUP_896 (0xEu << 24) /**< \brief (DACC_MR) 896 periods of DACClock */
#define DACC_MR_STARTUP_960 (0xFu << 24) /**< \brief (DACC_MR) 960 periods of DACClock */
#define DACC_MR_STARTUP_1024 (0x10u << 24) /**< \brief (DACC_MR) 1024 periods of DACClock */
#define DACC_MR_STARTUP_1088 (0x11u << 24) /**< \brief (DACC_MR) 1088 periods of DACClock */
#define DACC_MR_STARTUP_1152 (0x12u << 24) /**< \brief (DACC_MR) 1152 periods of DACClock */
#define DACC_MR_STARTUP_1216 (0x13u << 24) /**< \brief (DACC_MR) 1216 periods of DACClock */
#define DACC_MR_STARTUP_1280 (0x14u << 24) /**< \brief (DACC_MR) 1280 periods of DACClock */
#define DACC_MR_STARTUP_1344 (0x15u << 24) /**< \brief (DACC_MR) 1344 periods of DACClock */
#define DACC_MR_STARTUP_1408 (0x16u << 24) /**< \brief (DACC_MR) 1408 periods of DACClock */
#define DACC_MR_STARTUP_1472 (0x17u << 24) /**< \brief (DACC_MR) 1472 periods of DACClock */
#define DACC_MR_STARTUP_1536 (0x18u << 24) /**< \brief (DACC_MR) 1536 periods of DACClock */
#define DACC_MR_STARTUP_1600 (0x19u << 24) /**< \brief (DACC_MR) 1600 periods of DACClock */
#define DACC_MR_STARTUP_1664 (0x1Au << 24) /**< \brief (DACC_MR) 1664 periods of DACClock */
#define DACC_MR_STARTUP_1728 (0x1Bu << 24) /**< \brief (DACC_MR) 1728 periods of DACClock */
#define DACC_MR_STARTUP_1792 (0x1Cu << 24) /**< \brief (DACC_MR) 1792 periods of DACClock */
#define DACC_MR_STARTUP_1856 (0x1Du << 24) /**< \brief (DACC_MR) 1856 periods of DACClock */
#define DACC_MR_STARTUP_1920 (0x1Eu << 24) /**< \brief (DACC_MR) 1920 periods of DACClock */
#define DACC_MR_STARTUP_1984 (0x1Fu << 24) /**< \brief (DACC_MR) 1984 periods of DACClock */
/* -------- DACC_CHER : (DACC Offset: 0x10) Channel Enable Register -------- */
#define DACC_CHER_CH0 (0x1u << 0) /**< \brief (DACC_CHER) Channel 0 Enable */
#define DACC_CHER_CH1 (0x1u << 1) /**< \brief (DACC_CHER) Channel 1 Enable */
/* -------- DACC_CHDR : (DACC Offset: 0x14) Channel Disable Register -------- */
#define DACC_CHDR_CH0 (0x1u << 0) /**< \brief (DACC_CHDR) Channel 0 Disable */
#define DACC_CHDR_CH1 (0x1u << 1) /**< \brief (DACC_CHDR) Channel 1 Disable */
/* -------- DACC_CHSR : (DACC Offset: 0x18) Channel Status Register -------- */
#define DACC_CHSR_CH0 (0x1u << 0) /**< \brief (DACC_CHSR) Channel 0 Status */
#define DACC_CHSR_CH1 (0x1u << 1) /**< \brief (DACC_CHSR) Channel 1 Status */
/* -------- DACC_CDR : (DACC Offset: 0x20) Conversion Data Register -------- */
#define DACC_CDR_DATA_Pos 0
#define DACC_CDR_DATA_Msk (0xffffffffu << DACC_CDR_DATA_Pos) /**< \brief (DACC_CDR) Data to Convert */
#define DACC_CDR_DATA(value) ((DACC_CDR_DATA_Msk & ((value) << DACC_CDR_DATA_Pos)))
/* -------- DACC_IER : (DACC Offset: 0x24) Interrupt Enable Register -------- */
#define DACC_IER_TXRDY (0x1u << 0) /**< \brief (DACC_IER) Transmit Ready Interrupt Enable */
#define DACC_IER_EOC (0x1u << 1) /**< \brief (DACC_IER) End of Conversion Interrupt Enable */
#define DACC_IER_ENDTX (0x1u << 2) /**< \brief (DACC_IER) End of Transmit Buffer Interrupt Enable */
#define DACC_IER_TXBUFE (0x1u << 3) /**< \brief (DACC_IER) Transmit Buffer Empty Interrupt Enable */
/* -------- DACC_IDR : (DACC Offset: 0x28) Interrupt Disable Register -------- */
#define DACC_IDR_TXRDY (0x1u << 0) /**< \brief (DACC_IDR) Transmit Ready Interrupt Disable. */
#define DACC_IDR_EOC (0x1u << 1) /**< \brief (DACC_IDR) End of Conversion Interrupt Disable */
#define DACC_IDR_ENDTX (0x1u << 2) /**< \brief (DACC_IDR) End of Transmit Buffer Interrupt Disable */
#define DACC_IDR_TXBUFE (0x1u << 3) /**< \brief (DACC_IDR) Transmit Buffer Empty Interrupt Disable */
/* -------- DACC_IMR : (DACC Offset: 0x2C) Interrupt Mask Register -------- */
#define DACC_IMR_TXRDY (0x1u << 0) /**< \brief (DACC_IMR) Transmit Ready Interrupt Mask */
#define DACC_IMR_EOC (0x1u << 1) /**< \brief (DACC_IMR) End of Conversion Interrupt Mask */
#define DACC_IMR_ENDTX (0x1u << 2) /**< \brief (DACC_IMR) End of Transmit Buffer Interrupt Mask */
#define DACC_IMR_TXBUFE (0x1u << 3) /**< \brief (DACC_IMR) Transmit Buffer Empty Interrupt Mask */
/* -------- DACC_ISR : (DACC Offset: 0x30) Interrupt Status Register -------- */
#define DACC_ISR_TXRDY (0x1u << 0) /**< \brief (DACC_ISR) Transmit Ready Interrupt Flag */
#define DACC_ISR_EOC (0x1u << 1) /**< \brief (DACC_ISR) End of Conversion Interrupt Flag */
#define DACC_ISR_ENDTX (0x1u << 2) /**< \brief (DACC_ISR) End of DMA Interrupt Flag */
#define DACC_ISR_TXBUFE (0x1u << 3) /**< \brief (DACC_ISR) Transmit Buffer Empty */
/* -------- DACC_ACR : (DACC Offset: 0x94) Analog Current Register -------- */
#define DACC_ACR_IBCTLCH0_Pos 0
#define DACC_ACR_IBCTLCH0_Msk (0x3u << DACC_ACR_IBCTLCH0_Pos) /**< \brief (DACC_ACR) Analog Output Current Control */
#define DACC_ACR_IBCTLCH0(value) ((DACC_ACR_IBCTLCH0_Msk & ((value) << DACC_ACR_IBCTLCH0_Pos)))
#define DACC_ACR_IBCTLCH1_Pos 2
#define DACC_ACR_IBCTLCH1_Msk (0x3u << DACC_ACR_IBCTLCH1_Pos) /**< \brief (DACC_ACR) Analog Output Current Control */
#define DACC_ACR_IBCTLCH1(value) ((DACC_ACR_IBCTLCH1_Msk & ((value) << DACC_ACR_IBCTLCH1_Pos)))
#define DACC_ACR_IBCTLDACCORE_Pos 8
#define DACC_ACR_IBCTLDACCORE_Msk (0x3u << DACC_ACR_IBCTLDACCORE_Pos) /**< \brief (DACC_ACR) Bias Current Control for DAC Core */
#define DACC_ACR_IBCTLDACCORE(value) ((DACC_ACR_IBCTLDACCORE_Msk & ((value) << DACC_ACR_IBCTLDACCORE_Pos)))
/* -------- DACC_WPMR : (DACC Offset: 0xE4) Write Protect Mode register -------- */
#define DACC_WPMR_WPEN (0x1u << 0) /**< \brief (DACC_WPMR) Write Protect Enable */
#define DACC_WPMR_WPKEY_Pos 8
#define DACC_WPMR_WPKEY_Msk (0xffffffu << DACC_WPMR_WPKEY_Pos) /**< \brief (DACC_WPMR) Write Protect KEY */
#define DACC_WPMR_WPKEY(value) ((DACC_WPMR_WPKEY_Msk & ((value) << DACC_WPMR_WPKEY_Pos)))
/* -------- DACC_WPSR : (DACC Offset: 0xE8) Write Protect Status register -------- */
#define DACC_WPSR_WPROTERR (0x1u << 0) /**< \brief (DACC_WPSR) Write protection error */
#define DACC_WPSR_WPROTADDR_Pos 8
#define DACC_WPSR_WPROTADDR_Msk (0xffu << DACC_WPSR_WPROTADDR_Pos) /**< \brief (DACC_WPSR) Write protection error address */
/* -------- DACC_TPR : (DACC Offset: 0x108) Transmit Pointer Register -------- */
#define DACC_TPR_TXPTR_Pos 0
#define DACC_TPR_TXPTR_Msk (0xffffffffu << DACC_TPR_TXPTR_Pos) /**< \brief (DACC_TPR) Transmit Counter Register */
#define DACC_TPR_TXPTR(value) ((DACC_TPR_TXPTR_Msk & ((value) << DACC_TPR_TXPTR_Pos)))
/* -------- DACC_TCR : (DACC Offset: 0x10C) Transmit Counter Register -------- */
#define DACC_TCR_TXCTR_Pos 0
#define DACC_TCR_TXCTR_Msk (0xffffu << DACC_TCR_TXCTR_Pos) /**< \brief (DACC_TCR) Transmit Counter Register */
#define DACC_TCR_TXCTR(value) ((DACC_TCR_TXCTR_Msk & ((value) << DACC_TCR_TXCTR_Pos)))
/* -------- DACC_TNPR : (DACC Offset: 0x118) Transmit Next Pointer Register -------- */
#define DACC_TNPR_TXNPTR_Pos 0
#define DACC_TNPR_TXNPTR_Msk (0xffffffffu << DACC_TNPR_TXNPTR_Pos) /**< \brief (DACC_TNPR) Transmit Next Pointer */
#define DACC_TNPR_TXNPTR(value) ((DACC_TNPR_TXNPTR_Msk & ((value) << DACC_TNPR_TXNPTR_Pos)))
/* -------- DACC_TNCR : (DACC Offset: 0x11C) Transmit Next Counter Register -------- */
#define DACC_TNCR_TXNCTR_Pos 0
#define DACC_TNCR_TXNCTR_Msk (0xffffu << DACC_TNCR_TXNCTR_Pos) /**< \brief (DACC_TNCR) Transmit Counter Next */
#define DACC_TNCR_TXNCTR(value) ((DACC_TNCR_TXNCTR_Msk & ((value) << DACC_TNCR_TXNCTR_Pos)))
/* -------- DACC_PTCR : (DACC Offset: 0x120) Transfer Control Register -------- */
#define DACC_PTCR_RXTEN (0x1u << 0) /**< \brief (DACC_PTCR) Receiver Transfer Enable */
#define DACC_PTCR_RXTDIS (0x1u << 1) /**< \brief (DACC_PTCR) Receiver Transfer Disable */
#define DACC_PTCR_TXTEN (0x1u << 8) /**< \brief (DACC_PTCR) Transmitter Transfer Enable */
#define DACC_PTCR_TXTDIS (0x1u << 9) /**< \brief (DACC_PTCR) Transmitter Transfer Disable */
/* -------- DACC_PTSR : (DACC Offset: 0x124) Transfer Status Register -------- */
#define DACC_PTSR_RXTEN (0x1u << 0) /**< \brief (DACC_PTSR) Receiver Transfer Enable */
#define DACC_PTSR_TXTEN (0x1u << 8) /**< \brief (DACC_PTSR) Transmitter Transfer Enable */
/*@}*/
#endif /* _SAM3XA_DACC_COMPONENT_ */

View File

@@ -0,0 +1,367 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2012, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _SAM3XA_DMAC_COMPONENT_
#define _SAM3XA_DMAC_COMPONENT_
/* ============================================================================= */
/** SOFTWARE API DEFINITION FOR DMA Controller */
/* ============================================================================= */
/** \addtogroup SAM3XA_DMAC DMA Controller */
/*@{*/
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
/** \brief DmacCh_num hardware registers */
typedef struct {
RwReg DMAC_SADDR; /**< \brief (DmacCh_num Offset: 0x0) DMAC Channel Source Address Register */
RwReg DMAC_DADDR; /**< \brief (DmacCh_num Offset: 0x4) DMAC Channel Destination Address Register */
RwReg DMAC_DSCR; /**< \brief (DmacCh_num Offset: 0x8) DMAC Channel Descriptor Address Register */
RwReg DMAC_CTRLA; /**< \brief (DmacCh_num Offset: 0xC) DMAC Channel Control A Register */
RwReg DMAC_CTRLB; /**< \brief (DmacCh_num Offset: 0x10) DMAC Channel Control B Register */
RwReg DMAC_CFG; /**< \brief (DmacCh_num Offset: 0x14) DMAC Channel Configuration Register */
RoReg Reserved1[4];
} DmacCh_num;
/** \brief Dmac hardware registers */
#define DMACCH_NUM_NUMBER 6
typedef struct {
RwReg DMAC_GCFG; /**< \brief (Dmac Offset: 0x000) DMAC Global Configuration Register */
RwReg DMAC_EN; /**< \brief (Dmac Offset: 0x004) DMAC Enable Register */
RwReg DMAC_SREQ; /**< \brief (Dmac Offset: 0x008) DMAC Software Single Request Register */
RwReg DMAC_CREQ; /**< \brief (Dmac Offset: 0x00C) DMAC Software Chunk Transfer Request Register */
RwReg DMAC_LAST; /**< \brief (Dmac Offset: 0x010) DMAC Software Last Transfer Flag Register */
RoReg Reserved1[1];
WoReg DMAC_EBCIER; /**< \brief (Dmac Offset: 0x018) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer Transfer Completed Interrupt Enable register. */
WoReg DMAC_EBCIDR; /**< \brief (Dmac Offset: 0x01C) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer Transfer Completed Interrupt Disable register. */
RoReg DMAC_EBCIMR; /**< \brief (Dmac Offset: 0x020) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer transfer completed Mask Register. */
RoReg DMAC_EBCISR; /**< \brief (Dmac Offset: 0x024) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer transfer completed Status Register. */
WoReg DMAC_CHER; /**< \brief (Dmac Offset: 0x028) DMAC Channel Handler Enable Register */
WoReg DMAC_CHDR; /**< \brief (Dmac Offset: 0x02C) DMAC Channel Handler Disable Register */
RoReg DMAC_CHSR; /**< \brief (Dmac Offset: 0x030) DMAC Channel Handler Status Register */
RoReg Reserved2[2];
DmacCh_num DMAC_CH_NUM[DMACCH_NUM_NUMBER]; /**< \brief (Dmac Offset: 0x3C) ch_num = 0 .. 5 */
RoReg Reserved3[46];
RwReg DMAC_WPMR; /**< \brief (Dmac Offset: 0x1E4) DMAC Write Protect Mode Register */
RoReg DMAC_WPSR; /**< \brief (Dmac Offset: 0x1E8) DMAC Write Protect Status Register */
} Dmac;
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
/* -------- DMAC_GCFG : (DMAC Offset: 0x000) DMAC Global Configuration Register -------- */
#define DMAC_GCFG_ARB_CFG (0x1u << 4) /**< \brief (DMAC_GCFG) Arbiter Configuration */
#define DMAC_GCFG_ARB_CFG_FIXED (0x0u << 4) /**< \brief (DMAC_GCFG) Fixed priority arbiter. */
#define DMAC_GCFG_ARB_CFG_ROUND_ROBIN (0x1u << 4) /**< \brief (DMAC_GCFG) Modified round robin arbiter. */
/* -------- DMAC_EN : (DMAC Offset: 0x004) DMAC Enable Register -------- */
#define DMAC_EN_ENABLE (0x1u << 0) /**< \brief (DMAC_EN) */
/* -------- DMAC_SREQ : (DMAC Offset: 0x008) DMAC Software Single Request Register -------- */
#define DMAC_SREQ_SSREQ0 (0x1u << 0) /**< \brief (DMAC_SREQ) Source Request */
#define DMAC_SREQ_DSREQ0 (0x1u << 1) /**< \brief (DMAC_SREQ) Destination Request */
#define DMAC_SREQ_SSREQ1 (0x1u << 2) /**< \brief (DMAC_SREQ) Source Request */
#define DMAC_SREQ_DSREQ1 (0x1u << 3) /**< \brief (DMAC_SREQ) Destination Request */
#define DMAC_SREQ_SSREQ2 (0x1u << 4) /**< \brief (DMAC_SREQ) Source Request */
#define DMAC_SREQ_DSREQ2 (0x1u << 5) /**< \brief (DMAC_SREQ) Destination Request */
#define DMAC_SREQ_SSREQ3 (0x1u << 6) /**< \brief (DMAC_SREQ) Source Request */
#define DMAC_SREQ_DSREQ3 (0x1u << 7) /**< \brief (DMAC_SREQ) Destination Request */
#define DMAC_SREQ_SSREQ4 (0x1u << 8) /**< \brief (DMAC_SREQ) Source Request */
#define DMAC_SREQ_DSREQ4 (0x1u << 9) /**< \brief (DMAC_SREQ) Destination Request */
#define DMAC_SREQ_SSREQ5 (0x1u << 10) /**< \brief (DMAC_SREQ) Source Request */
#define DMAC_SREQ_DSREQ5 (0x1u << 11) /**< \brief (DMAC_SREQ) Destination Request */
/* -------- DMAC_CREQ : (DMAC Offset: 0x00C) DMAC Software Chunk Transfer Request Register -------- */
#define DMAC_CREQ_SCREQ0 (0x1u << 0) /**< \brief (DMAC_CREQ) Source Chunk Request */
#define DMAC_CREQ_DCREQ0 (0x1u << 1) /**< \brief (DMAC_CREQ) Destination Chunk Request */
#define DMAC_CREQ_SCREQ1 (0x1u << 2) /**< \brief (DMAC_CREQ) Source Chunk Request */
#define DMAC_CREQ_DCREQ1 (0x1u << 3) /**< \brief (DMAC_CREQ) Destination Chunk Request */
#define DMAC_CREQ_SCREQ2 (0x1u << 4) /**< \brief (DMAC_CREQ) Source Chunk Request */
#define DMAC_CREQ_DCREQ2 (0x1u << 5) /**< \brief (DMAC_CREQ) Destination Chunk Request */
#define DMAC_CREQ_SCREQ3 (0x1u << 6) /**< \brief (DMAC_CREQ) Source Chunk Request */
#define DMAC_CREQ_DCREQ3 (0x1u << 7) /**< \brief (DMAC_CREQ) Destination Chunk Request */
#define DMAC_CREQ_SCREQ4 (0x1u << 8) /**< \brief (DMAC_CREQ) Source Chunk Request */
#define DMAC_CREQ_DCREQ4 (0x1u << 9) /**< \brief (DMAC_CREQ) Destination Chunk Request */
#define DMAC_CREQ_SCREQ5 (0x1u << 10) /**< \brief (DMAC_CREQ) Source Chunk Request */
#define DMAC_CREQ_DCREQ5 (0x1u << 11) /**< \brief (DMAC_CREQ) Destination Chunk Request */
/* -------- DMAC_LAST : (DMAC Offset: 0x010) DMAC Software Last Transfer Flag Register -------- */
#define DMAC_LAST_SLAST0 (0x1u << 0) /**< \brief (DMAC_LAST) Source Last */
#define DMAC_LAST_DLAST0 (0x1u << 1) /**< \brief (DMAC_LAST) Destination Last */
#define DMAC_LAST_SLAST1 (0x1u << 2) /**< \brief (DMAC_LAST) Source Last */
#define DMAC_LAST_DLAST1 (0x1u << 3) /**< \brief (DMAC_LAST) Destination Last */
#define DMAC_LAST_SLAST2 (0x1u << 4) /**< \brief (DMAC_LAST) Source Last */
#define DMAC_LAST_DLAST2 (0x1u << 5) /**< \brief (DMAC_LAST) Destination Last */
#define DMAC_LAST_SLAST3 (0x1u << 6) /**< \brief (DMAC_LAST) Source Last */
#define DMAC_LAST_DLAST3 (0x1u << 7) /**< \brief (DMAC_LAST) Destination Last */
#define DMAC_LAST_SLAST4 (0x1u << 8) /**< \brief (DMAC_LAST) Source Last */
#define DMAC_LAST_DLAST4 (0x1u << 9) /**< \brief (DMAC_LAST) Destination Last */
#define DMAC_LAST_SLAST5 (0x1u << 10) /**< \brief (DMAC_LAST) Source Last */
#define DMAC_LAST_DLAST5 (0x1u << 11) /**< \brief (DMAC_LAST) Destination Last */
/* -------- DMAC_EBCIER : (DMAC Offset: 0x018) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer Transfer Completed Interrupt Enable register. -------- */
#define DMAC_EBCIER_BTC0 (0x1u << 0) /**< \brief (DMAC_EBCIER) Buffer Transfer Completed [5:0] */
#define DMAC_EBCIER_BTC1 (0x1u << 1) /**< \brief (DMAC_EBCIER) Buffer Transfer Completed [5:0] */
#define DMAC_EBCIER_BTC2 (0x1u << 2) /**< \brief (DMAC_EBCIER) Buffer Transfer Completed [5:0] */
#define DMAC_EBCIER_BTC3 (0x1u << 3) /**< \brief (DMAC_EBCIER) Buffer Transfer Completed [5:0] */
#define DMAC_EBCIER_BTC4 (0x1u << 4) /**< \brief (DMAC_EBCIER) Buffer Transfer Completed [5:0] */
#define DMAC_EBCIER_BTC5 (0x1u << 5) /**< \brief (DMAC_EBCIER) Buffer Transfer Completed [5:0] */
#define DMAC_EBCIER_CBTC0 (0x1u << 8) /**< \brief (DMAC_EBCIER) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCIER_CBTC1 (0x1u << 9) /**< \brief (DMAC_EBCIER) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCIER_CBTC2 (0x1u << 10) /**< \brief (DMAC_EBCIER) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCIER_CBTC3 (0x1u << 11) /**< \brief (DMAC_EBCIER) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCIER_CBTC4 (0x1u << 12) /**< \brief (DMAC_EBCIER) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCIER_CBTC5 (0x1u << 13) /**< \brief (DMAC_EBCIER) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCIER_ERR0 (0x1u << 16) /**< \brief (DMAC_EBCIER) Access Error [5:0] */
#define DMAC_EBCIER_ERR1 (0x1u << 17) /**< \brief (DMAC_EBCIER) Access Error [5:0] */
#define DMAC_EBCIER_ERR2 (0x1u << 18) /**< \brief (DMAC_EBCIER) Access Error [5:0] */
#define DMAC_EBCIER_ERR3 (0x1u << 19) /**< \brief (DMAC_EBCIER) Access Error [5:0] */
#define DMAC_EBCIER_ERR4 (0x1u << 20) /**< \brief (DMAC_EBCIER) Access Error [5:0] */
#define DMAC_EBCIER_ERR5 (0x1u << 21) /**< \brief (DMAC_EBCIER) Access Error [5:0] */
/* -------- DMAC_EBCIDR : (DMAC Offset: 0x01C) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer Transfer Completed Interrupt Disable register. -------- */
#define DMAC_EBCIDR_BTC0 (0x1u << 0) /**< \brief (DMAC_EBCIDR) Buffer Transfer Completed [5:0] */
#define DMAC_EBCIDR_BTC1 (0x1u << 1) /**< \brief (DMAC_EBCIDR) Buffer Transfer Completed [5:0] */
#define DMAC_EBCIDR_BTC2 (0x1u << 2) /**< \brief (DMAC_EBCIDR) Buffer Transfer Completed [5:0] */
#define DMAC_EBCIDR_BTC3 (0x1u << 3) /**< \brief (DMAC_EBCIDR) Buffer Transfer Completed [5:0] */
#define DMAC_EBCIDR_BTC4 (0x1u << 4) /**< \brief (DMAC_EBCIDR) Buffer Transfer Completed [5:0] */
#define DMAC_EBCIDR_BTC5 (0x1u << 5) /**< \brief (DMAC_EBCIDR) Buffer Transfer Completed [5:0] */
#define DMAC_EBCIDR_CBTC0 (0x1u << 8) /**< \brief (DMAC_EBCIDR) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCIDR_CBTC1 (0x1u << 9) /**< \brief (DMAC_EBCIDR) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCIDR_CBTC2 (0x1u << 10) /**< \brief (DMAC_EBCIDR) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCIDR_CBTC3 (0x1u << 11) /**< \brief (DMAC_EBCIDR) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCIDR_CBTC4 (0x1u << 12) /**< \brief (DMAC_EBCIDR) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCIDR_CBTC5 (0x1u << 13) /**< \brief (DMAC_EBCIDR) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCIDR_ERR0 (0x1u << 16) /**< \brief (DMAC_EBCIDR) Access Error [5:0] */
#define DMAC_EBCIDR_ERR1 (0x1u << 17) /**< \brief (DMAC_EBCIDR) Access Error [5:0] */
#define DMAC_EBCIDR_ERR2 (0x1u << 18) /**< \brief (DMAC_EBCIDR) Access Error [5:0] */
#define DMAC_EBCIDR_ERR3 (0x1u << 19) /**< \brief (DMAC_EBCIDR) Access Error [5:0] */
#define DMAC_EBCIDR_ERR4 (0x1u << 20) /**< \brief (DMAC_EBCIDR) Access Error [5:0] */
#define DMAC_EBCIDR_ERR5 (0x1u << 21) /**< \brief (DMAC_EBCIDR) Access Error [5:0] */
/* -------- DMAC_EBCIMR : (DMAC Offset: 0x020) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer transfer completed Mask Register. -------- */
#define DMAC_EBCIMR_BTC0 (0x1u << 0) /**< \brief (DMAC_EBCIMR) Buffer Transfer Completed [5:0] */
#define DMAC_EBCIMR_BTC1 (0x1u << 1) /**< \brief (DMAC_EBCIMR) Buffer Transfer Completed [5:0] */
#define DMAC_EBCIMR_BTC2 (0x1u << 2) /**< \brief (DMAC_EBCIMR) Buffer Transfer Completed [5:0] */
#define DMAC_EBCIMR_BTC3 (0x1u << 3) /**< \brief (DMAC_EBCIMR) Buffer Transfer Completed [5:0] */
#define DMAC_EBCIMR_BTC4 (0x1u << 4) /**< \brief (DMAC_EBCIMR) Buffer Transfer Completed [5:0] */
#define DMAC_EBCIMR_BTC5 (0x1u << 5) /**< \brief (DMAC_EBCIMR) Buffer Transfer Completed [5:0] */
#define DMAC_EBCIMR_CBTC0 (0x1u << 8) /**< \brief (DMAC_EBCIMR) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCIMR_CBTC1 (0x1u << 9) /**< \brief (DMAC_EBCIMR) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCIMR_CBTC2 (0x1u << 10) /**< \brief (DMAC_EBCIMR) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCIMR_CBTC3 (0x1u << 11) /**< \brief (DMAC_EBCIMR) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCIMR_CBTC4 (0x1u << 12) /**< \brief (DMAC_EBCIMR) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCIMR_CBTC5 (0x1u << 13) /**< \brief (DMAC_EBCIMR) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCIMR_ERR0 (0x1u << 16) /**< \brief (DMAC_EBCIMR) Access Error [5:0] */
#define DMAC_EBCIMR_ERR1 (0x1u << 17) /**< \brief (DMAC_EBCIMR) Access Error [5:0] */
#define DMAC_EBCIMR_ERR2 (0x1u << 18) /**< \brief (DMAC_EBCIMR) Access Error [5:0] */
#define DMAC_EBCIMR_ERR3 (0x1u << 19) /**< \brief (DMAC_EBCIMR) Access Error [5:0] */
#define DMAC_EBCIMR_ERR4 (0x1u << 20) /**< \brief (DMAC_EBCIMR) Access Error [5:0] */
#define DMAC_EBCIMR_ERR5 (0x1u << 21) /**< \brief (DMAC_EBCIMR) Access Error [5:0] */
/* -------- DMAC_EBCISR : (DMAC Offset: 0x024) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer transfer completed Status Register. -------- */
#define DMAC_EBCISR_BTC0 (0x1u << 0) /**< \brief (DMAC_EBCISR) Buffer Transfer Completed [5:0] */
#define DMAC_EBCISR_BTC1 (0x1u << 1) /**< \brief (DMAC_EBCISR) Buffer Transfer Completed [5:0] */
#define DMAC_EBCISR_BTC2 (0x1u << 2) /**< \brief (DMAC_EBCISR) Buffer Transfer Completed [5:0] */
#define DMAC_EBCISR_BTC3 (0x1u << 3) /**< \brief (DMAC_EBCISR) Buffer Transfer Completed [5:0] */
#define DMAC_EBCISR_BTC4 (0x1u << 4) /**< \brief (DMAC_EBCISR) Buffer Transfer Completed [5:0] */
#define DMAC_EBCISR_BTC5 (0x1u << 5) /**< \brief (DMAC_EBCISR) Buffer Transfer Completed [5:0] */
#define DMAC_EBCISR_CBTC0 (0x1u << 8) /**< \brief (DMAC_EBCISR) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCISR_CBTC1 (0x1u << 9) /**< \brief (DMAC_EBCISR) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCISR_CBTC2 (0x1u << 10) /**< \brief (DMAC_EBCISR) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCISR_CBTC3 (0x1u << 11) /**< \brief (DMAC_EBCISR) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCISR_CBTC4 (0x1u << 12) /**< \brief (DMAC_EBCISR) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCISR_CBTC5 (0x1u << 13) /**< \brief (DMAC_EBCISR) Chained Buffer Transfer Completed [5:0] */
#define DMAC_EBCISR_ERR0 (0x1u << 16) /**< \brief (DMAC_EBCISR) Access Error [5:0] */
#define DMAC_EBCISR_ERR1 (0x1u << 17) /**< \brief (DMAC_EBCISR) Access Error [5:0] */
#define DMAC_EBCISR_ERR2 (0x1u << 18) /**< \brief (DMAC_EBCISR) Access Error [5:0] */
#define DMAC_EBCISR_ERR3 (0x1u << 19) /**< \brief (DMAC_EBCISR) Access Error [5:0] */
#define DMAC_EBCISR_ERR4 (0x1u << 20) /**< \brief (DMAC_EBCISR) Access Error [5:0] */
#define DMAC_EBCISR_ERR5 (0x1u << 21) /**< \brief (DMAC_EBCISR) Access Error [5:0] */
/* -------- DMAC_CHER : (DMAC Offset: 0x028) DMAC Channel Handler Enable Register -------- */
#define DMAC_CHER_ENA0 (0x1u << 0) /**< \brief (DMAC_CHER) Enable [5:0] */
#define DMAC_CHER_ENA1 (0x1u << 1) /**< \brief (DMAC_CHER) Enable [5:0] */
#define DMAC_CHER_ENA2 (0x1u << 2) /**< \brief (DMAC_CHER) Enable [5:0] */
#define DMAC_CHER_ENA3 (0x1u << 3) /**< \brief (DMAC_CHER) Enable [5:0] */
#define DMAC_CHER_ENA4 (0x1u << 4) /**< \brief (DMAC_CHER) Enable [5:0] */
#define DMAC_CHER_ENA5 (0x1u << 5) /**< \brief (DMAC_CHER) Enable [5:0] */
#define DMAC_CHER_SUSP0 (0x1u << 8) /**< \brief (DMAC_CHER) Suspend [5:0] */
#define DMAC_CHER_SUSP1 (0x1u << 9) /**< \brief (DMAC_CHER) Suspend [5:0] */
#define DMAC_CHER_SUSP2 (0x1u << 10) /**< \brief (DMAC_CHER) Suspend [5:0] */
#define DMAC_CHER_SUSP3 (0x1u << 11) /**< \brief (DMAC_CHER) Suspend [5:0] */
#define DMAC_CHER_SUSP4 (0x1u << 12) /**< \brief (DMAC_CHER) Suspend [5:0] */
#define DMAC_CHER_SUSP5 (0x1u << 13) /**< \brief (DMAC_CHER) Suspend [5:0] */
#define DMAC_CHER_KEEP0 (0x1u << 24) /**< \brief (DMAC_CHER) Keep on [5:0] */
#define DMAC_CHER_KEEP1 (0x1u << 25) /**< \brief (DMAC_CHER) Keep on [5:0] */
#define DMAC_CHER_KEEP2 (0x1u << 26) /**< \brief (DMAC_CHER) Keep on [5:0] */
#define DMAC_CHER_KEEP3 (0x1u << 27) /**< \brief (DMAC_CHER) Keep on [5:0] */
#define DMAC_CHER_KEEP4 (0x1u << 28) /**< \brief (DMAC_CHER) Keep on [5:0] */
#define DMAC_CHER_KEEP5 (0x1u << 29) /**< \brief (DMAC_CHER) Keep on [5:0] */
/* -------- DMAC_CHDR : (DMAC Offset: 0x02C) DMAC Channel Handler Disable Register -------- */
#define DMAC_CHDR_DIS0 (0x1u << 0) /**< \brief (DMAC_CHDR) Disable [5:0] */
#define DMAC_CHDR_DIS1 (0x1u << 1) /**< \brief (DMAC_CHDR) Disable [5:0] */
#define DMAC_CHDR_DIS2 (0x1u << 2) /**< \brief (DMAC_CHDR) Disable [5:0] */
#define DMAC_CHDR_DIS3 (0x1u << 3) /**< \brief (DMAC_CHDR) Disable [5:0] */
#define DMAC_CHDR_DIS4 (0x1u << 4) /**< \brief (DMAC_CHDR) Disable [5:0] */
#define DMAC_CHDR_DIS5 (0x1u << 5) /**< \brief (DMAC_CHDR) Disable [5:0] */
#define DMAC_CHDR_RES0 (0x1u << 8) /**< \brief (DMAC_CHDR) Resume [5:0] */
#define DMAC_CHDR_RES1 (0x1u << 9) /**< \brief (DMAC_CHDR) Resume [5:0] */
#define DMAC_CHDR_RES2 (0x1u << 10) /**< \brief (DMAC_CHDR) Resume [5:0] */
#define DMAC_CHDR_RES3 (0x1u << 11) /**< \brief (DMAC_CHDR) Resume [5:0] */
#define DMAC_CHDR_RES4 (0x1u << 12) /**< \brief (DMAC_CHDR) Resume [5:0] */
#define DMAC_CHDR_RES5 (0x1u << 13) /**< \brief (DMAC_CHDR) Resume [5:0] */
/* -------- DMAC_CHSR : (DMAC Offset: 0x030) DMAC Channel Handler Status Register -------- */
#define DMAC_CHSR_ENA0 (0x1u << 0) /**< \brief (DMAC_CHSR) Enable [5:0] */
#define DMAC_CHSR_ENA1 (0x1u << 1) /**< \brief (DMAC_CHSR) Enable [5:0] */
#define DMAC_CHSR_ENA2 (0x1u << 2) /**< \brief (DMAC_CHSR) Enable [5:0] */
#define DMAC_CHSR_ENA3 (0x1u << 3) /**< \brief (DMAC_CHSR) Enable [5:0] */
#define DMAC_CHSR_ENA4 (0x1u << 4) /**< \brief (DMAC_CHSR) Enable [5:0] */
#define DMAC_CHSR_ENA5 (0x1u << 5) /**< \brief (DMAC_CHSR) Enable [5:0] */
#define DMAC_CHSR_SUSP0 (0x1u << 8) /**< \brief (DMAC_CHSR) Suspend [5:0] */
#define DMAC_CHSR_SUSP1 (0x1u << 9) /**< \brief (DMAC_CHSR) Suspend [5:0] */
#define DMAC_CHSR_SUSP2 (0x1u << 10) /**< \brief (DMAC_CHSR) Suspend [5:0] */
#define DMAC_CHSR_SUSP3 (0x1u << 11) /**< \brief (DMAC_CHSR) Suspend [5:0] */
#define DMAC_CHSR_SUSP4 (0x1u << 12) /**< \brief (DMAC_CHSR) Suspend [5:0] */
#define DMAC_CHSR_SUSP5 (0x1u << 13) /**< \brief (DMAC_CHSR) Suspend [5:0] */
#define DMAC_CHSR_EMPT0 (0x1u << 16) /**< \brief (DMAC_CHSR) Empty [5:0] */
#define DMAC_CHSR_EMPT1 (0x1u << 17) /**< \brief (DMAC_CHSR) Empty [5:0] */
#define DMAC_CHSR_EMPT2 (0x1u << 18) /**< \brief (DMAC_CHSR) Empty [5:0] */
#define DMAC_CHSR_EMPT3 (0x1u << 19) /**< \brief (DMAC_CHSR) Empty [5:0] */
#define DMAC_CHSR_EMPT4 (0x1u << 20) /**< \brief (DMAC_CHSR) Empty [5:0] */
#define DMAC_CHSR_EMPT5 (0x1u << 21) /**< \brief (DMAC_CHSR) Empty [5:0] */
#define DMAC_CHSR_STAL0 (0x1u << 24) /**< \brief (DMAC_CHSR) Stalled [5:0] */
#define DMAC_CHSR_STAL1 (0x1u << 25) /**< \brief (DMAC_CHSR) Stalled [5:0] */
#define DMAC_CHSR_STAL2 (0x1u << 26) /**< \brief (DMAC_CHSR) Stalled [5:0] */
#define DMAC_CHSR_STAL3 (0x1u << 27) /**< \brief (DMAC_CHSR) Stalled [5:0] */
#define DMAC_CHSR_STAL4 (0x1u << 28) /**< \brief (DMAC_CHSR) Stalled [5:0] */
#define DMAC_CHSR_STAL5 (0x1u << 29) /**< \brief (DMAC_CHSR) Stalled [5:0] */
/* -------- DMAC_SADDR : (DMAC Offset: N/A) DMAC Channel Source Address Register -------- */
#define DMAC_SADDR_SADDR_Pos 0
#define DMAC_SADDR_SADDR_Msk (0xffffffffu << DMAC_SADDR_SADDR_Pos) /**< \brief (DMAC_SADDR) Channel x Source Address */
#define DMAC_SADDR_SADDR(value) ((DMAC_SADDR_SADDR_Msk & ((value) << DMAC_SADDR_SADDR_Pos)))
/* -------- DMAC_DADDR : (DMAC Offset: N/A) DMAC Channel Destination Address Register -------- */
#define DMAC_DADDR_DADDR_Pos 0
#define DMAC_DADDR_DADDR_Msk (0xffffffffu << DMAC_DADDR_DADDR_Pos) /**< \brief (DMAC_DADDR) Channel x Destination Address */
#define DMAC_DADDR_DADDR(value) ((DMAC_DADDR_DADDR_Msk & ((value) << DMAC_DADDR_DADDR_Pos)))
/* -------- DMAC_DSCR : (DMAC Offset: N/A) DMAC Channel Descriptor Address Register -------- */
#define DMAC_DSCR_DSCR_Pos 2
#define DMAC_DSCR_DSCR_Msk (0x3fffffffu << DMAC_DSCR_DSCR_Pos) /**< \brief (DMAC_DSCR) Buffer Transfer Descriptor Address */
#define DMAC_DSCR_DSCR(value) ((DMAC_DSCR_DSCR_Msk & ((value) << DMAC_DSCR_DSCR_Pos)))
/* -------- DMAC_CTRLA : (DMAC Offset: N/A) DMAC Channel Control A Register -------- */
#define DMAC_CTRLA_BTSIZE_Pos 0
#define DMAC_CTRLA_BTSIZE_Msk (0xffffu << DMAC_CTRLA_BTSIZE_Pos) /**< \brief (DMAC_CTRLA) Buffer Transfer Size */
#define DMAC_CTRLA_BTSIZE(value) ((DMAC_CTRLA_BTSIZE_Msk & ((value) << DMAC_CTRLA_BTSIZE_Pos)))
#define DMAC_CTRLA_SCSIZE_Pos 16
#define DMAC_CTRLA_SCSIZE_Msk (0x7u << DMAC_CTRLA_SCSIZE_Pos) /**< \brief (DMAC_CTRLA) Source Chunk Transfer Size. */
#define DMAC_CTRLA_SCSIZE_CHK_1 (0x0u << 16) /**< \brief (DMAC_CTRLA) 1 data transferred */
#define DMAC_CTRLA_SCSIZE_CHK_4 (0x1u << 16) /**< \brief (DMAC_CTRLA) 4 data transferred */
#define DMAC_CTRLA_SCSIZE_CHK_8 (0x2u << 16) /**< \brief (DMAC_CTRLA) 8 data transferred */
#define DMAC_CTRLA_SCSIZE_CHK_16 (0x3u << 16) /**< \brief (DMAC_CTRLA) 16 data transferred */
#define DMAC_CTRLA_SCSIZE_CHK_32 (0x4u << 16) /**< \brief (DMAC_CTRLA) 32 data transferred */
#define DMAC_CTRLA_SCSIZE_CHK_64 (0x5u << 16) /**< \brief (DMAC_CTRLA) 64 data transferred */
#define DMAC_CTRLA_SCSIZE_CHK_128 (0x6u << 16) /**< \brief (DMAC_CTRLA) 128 data transferred */
#define DMAC_CTRLA_SCSIZE_CHK_256 (0x7u << 16) /**< \brief (DMAC_CTRLA) 256 data transferred */
#define DMAC_CTRLA_DCSIZE_Pos 20
#define DMAC_CTRLA_DCSIZE_Msk (0x7u << DMAC_CTRLA_DCSIZE_Pos) /**< \brief (DMAC_CTRLA) Destination Chunk Transfer Size */
#define DMAC_CTRLA_DCSIZE_CHK_1 (0x0u << 20) /**< \brief (DMAC_CTRLA) 1 data transferred */
#define DMAC_CTRLA_DCSIZE_CHK_4 (0x1u << 20) /**< \brief (DMAC_CTRLA) 4 data transferred */
#define DMAC_CTRLA_DCSIZE_CHK_8 (0x2u << 20) /**< \brief (DMAC_CTRLA) 8 data transferred */
#define DMAC_CTRLA_DCSIZE_CHK_16 (0x3u << 20) /**< \brief (DMAC_CTRLA) 16 data transferred */
#define DMAC_CTRLA_DCSIZE_CHK_32 (0x4u << 20) /**< \brief (DMAC_CTRLA) 32 data transferred */
#define DMAC_CTRLA_DCSIZE_CHK_64 (0x5u << 20) /**< \brief (DMAC_CTRLA) 64 data transferred */
#define DMAC_CTRLA_DCSIZE_CHK_128 (0x6u << 20) /**< \brief (DMAC_CTRLA) 128 data transferred */
#define DMAC_CTRLA_DCSIZE_CHK_256 (0x7u << 20) /**< \brief (DMAC_CTRLA) 256 data transferred */
#define DMAC_CTRLA_SRC_WIDTH_Pos 24
#define DMAC_CTRLA_SRC_WIDTH_Msk (0x3u << DMAC_CTRLA_SRC_WIDTH_Pos) /**< \brief (DMAC_CTRLA) Transfer Width for the Source */
#define DMAC_CTRLA_SRC_WIDTH_BYTE (0x0u << 24) /**< \brief (DMAC_CTRLA) the transfer size is set to 8-bit width */
#define DMAC_CTRLA_SRC_WIDTH_HALF_WORD (0x1u << 24) /**< \brief (DMAC_CTRLA) the transfer size is set to 16-bit width */
#define DMAC_CTRLA_SRC_WIDTH_WORD (0x2u << 24) /**< \brief (DMAC_CTRLA) the transfer size is set to 32-bit width */
#define DMAC_CTRLA_DST_WIDTH_Pos 28
#define DMAC_CTRLA_DST_WIDTH_Msk (0x3u << DMAC_CTRLA_DST_WIDTH_Pos) /**< \brief (DMAC_CTRLA) Transfer Width for the Destination */
#define DMAC_CTRLA_DST_WIDTH_BYTE (0x0u << 28) /**< \brief (DMAC_CTRLA) the transfer size is set to 8-bit width */
#define DMAC_CTRLA_DST_WIDTH_HALF_WORD (0x1u << 28) /**< \brief (DMAC_CTRLA) the transfer size is set to 16-bit width */
#define DMAC_CTRLA_DST_WIDTH_WORD (0x2u << 28) /**< \brief (DMAC_CTRLA) the transfer size is set to 32-bit width */
#define DMAC_CTRLA_DONE (0x1u << 31) /**< \brief (DMAC_CTRLA) */
/* -------- DMAC_CTRLB : (DMAC Offset: N/A) DMAC Channel Control B Register -------- */
#define DMAC_CTRLB_SRC_DSCR (0x1u << 16) /**< \brief (DMAC_CTRLB) Source Address Descriptor */
#define DMAC_CTRLB_SRC_DSCR_FETCH_FROM_MEM (0x0u << 16) /**< \brief (DMAC_CTRLB) Source address is updated when the descriptor is fetched from the memory. */
#define DMAC_CTRLB_SRC_DSCR_FETCH_DISABLE (0x1u << 16) /**< \brief (DMAC_CTRLB) Buffer Descriptor Fetch operation is disabled for the source. */
#define DMAC_CTRLB_DST_DSCR (0x1u << 20) /**< \brief (DMAC_CTRLB) Destination Address Descriptor */
#define DMAC_CTRLB_DST_DSCR_FETCH_FROM_MEM (0x0u << 20) /**< \brief (DMAC_CTRLB) Destination address is updated when the descriptor is fetched from the memory. */
#define DMAC_CTRLB_DST_DSCR_FETCH_DISABLE (0x1u << 20) /**< \brief (DMAC_CTRLB) Buffer Descriptor Fetch operation is disabled for the destination. */
#define DMAC_CTRLB_FC_Pos 21
#define DMAC_CTRLB_FC_Msk (0x7u << DMAC_CTRLB_FC_Pos) /**< \brief (DMAC_CTRLB) Flow Control */
#define DMAC_CTRLB_FC_MEM2MEM_DMA_FC (0x0u << 21) /**< \brief (DMAC_CTRLB) Memory-to-Memory Transfer DMAC is flow controller */
#define DMAC_CTRLB_FC_MEM2PER_DMA_FC (0x1u << 21) /**< \brief (DMAC_CTRLB) Memory-to-Peripheral Transfer DMAC is flow controller */
#define DMAC_CTRLB_FC_PER2MEM_DMA_FC (0x2u << 21) /**< \brief (DMAC_CTRLB) Peripheral-to-Memory Transfer DMAC is flow controller */
#define DMAC_CTRLB_FC_PER2PER_DMA_FC (0x3u << 21) /**< \brief (DMAC_CTRLB) Peripheral-to-Peripheral Transfer DMAC is flow controller */
#define DMAC_CTRLB_SRC_INCR_Pos 24
#define DMAC_CTRLB_SRC_INCR_Msk (0x3u << DMAC_CTRLB_SRC_INCR_Pos) /**< \brief (DMAC_CTRLB) Incrementing, Decrementing or Fixed Address for the Source */
#define DMAC_CTRLB_SRC_INCR_INCREMENTING (0x0u << 24) /**< \brief (DMAC_CTRLB) The source address is incremented */
#define DMAC_CTRLB_SRC_INCR_DECREMENTING (0x1u << 24) /**< \brief (DMAC_CTRLB) The source address is decremented */
#define DMAC_CTRLB_SRC_INCR_FIXED (0x2u << 24) /**< \brief (DMAC_CTRLB) The source address remains unchanged */
#define DMAC_CTRLB_DST_INCR_Pos 28
#define DMAC_CTRLB_DST_INCR_Msk (0x3u << DMAC_CTRLB_DST_INCR_Pos) /**< \brief (DMAC_CTRLB) Incrementing, Decrementing or Fixed Address for the Destination */
#define DMAC_CTRLB_DST_INCR_INCREMENTING (0x0u << 28) /**< \brief (DMAC_CTRLB) The destination address is incremented */
#define DMAC_CTRLB_DST_INCR_DECREMENTING (0x1u << 28) /**< \brief (DMAC_CTRLB) The destination address is decremented */
#define DMAC_CTRLB_DST_INCR_FIXED (0x2u << 28) /**< \brief (DMAC_CTRLB) The destination address remains unchanged */
#define DMAC_CTRLB_IEN (0x1u << 30) /**< \brief (DMAC_CTRLB) */
/* -------- DMAC_CFG : (DMAC Offset: N/A) DMAC Channel Configuration Register -------- */
#define DMAC_CFG_SRC_PER_Pos 0
#define DMAC_CFG_SRC_PER_Msk (0xfu << DMAC_CFG_SRC_PER_Pos) /**< \brief (DMAC_CFG) Source with Peripheral identifier */
#define DMAC_CFG_SRC_PER(value) ((DMAC_CFG_SRC_PER_Msk & ((value) << DMAC_CFG_SRC_PER_Pos)))
#define DMAC_CFG_DST_PER_Pos 4
#define DMAC_CFG_DST_PER_Msk (0xfu << DMAC_CFG_DST_PER_Pos) /**< \brief (DMAC_CFG) Destination with Peripheral identifier */
#define DMAC_CFG_DST_PER(value) ((DMAC_CFG_DST_PER_Msk & ((value) << DMAC_CFG_DST_PER_Pos)))
#define DMAC_CFG_SRC_H2SEL (0x1u << 9) /**< \brief (DMAC_CFG) Software or Hardware Selection for the Source */
#define DMAC_CFG_SRC_H2SEL_SW (0x0u << 9) /**< \brief (DMAC_CFG) Software handshaking interface is used to trigger a transfer request. */
#define DMAC_CFG_SRC_H2SEL_HW (0x1u << 9) /**< \brief (DMAC_CFG) Hardware handshaking interface is used to trigger a transfer request. */
#define DMAC_CFG_DST_H2SEL (0x1u << 13) /**< \brief (DMAC_CFG) Software or Hardware Selection for the Destination */
#define DMAC_CFG_DST_H2SEL_SW (0x0u << 13) /**< \brief (DMAC_CFG) Software handshaking interface is used to trigger a transfer request. */
#define DMAC_CFG_DST_H2SEL_HW (0x1u << 13) /**< \brief (DMAC_CFG) Hardware handshaking interface is used to trigger a transfer request. */
#define DMAC_CFG_SOD (0x1u << 16) /**< \brief (DMAC_CFG) Stop On Done */
#define DMAC_CFG_SOD_DISABLE (0x0u << 16) /**< \brief (DMAC_CFG) STOP ON DONE disabled, the descriptor fetch operation ignores DONE Field of CTRLA register. */
#define DMAC_CFG_SOD_ENABLE (0x1u << 16) /**< \brief (DMAC_CFG) STOP ON DONE activated, the DMAC module is automatically disabled if DONE FIELD is set to 1. */
#define DMAC_CFG_LOCK_IF (0x1u << 20) /**< \brief (DMAC_CFG) Interface Lock */
#define DMAC_CFG_LOCK_IF_DISABLE (0x0u << 20) /**< \brief (DMAC_CFG) Interface Lock capability is disabled */
#define DMAC_CFG_LOCK_IF_ENABLE (0x1u << 20) /**< \brief (DMAC_CFG) Interface Lock capability is enabled */
#define DMAC_CFG_LOCK_B (0x1u << 21) /**< \brief (DMAC_CFG) Bus Lock */
#define DMAC_CFG_LOCK_B_DISABLE (0x0u << 21) /**< \brief (DMAC_CFG) AHB Bus Locking capability is disabled. */
#define DMAC_CFG_LOCK_IF_L (0x1u << 22) /**< \brief (DMAC_CFG) Master Interface Arbiter Lock */
#define DMAC_CFG_LOCK_IF_L_CHUNK (0x0u << 22) /**< \brief (DMAC_CFG) The Master Interface Arbiter is locked by the channel x for a chunk transfer. */
#define DMAC_CFG_LOCK_IF_L_BUFFER (0x1u << 22) /**< \brief (DMAC_CFG) The Master Interface Arbiter is locked by the channel x for a buffer transfer. */
#define DMAC_CFG_AHB_PROT_Pos 24
#define DMAC_CFG_AHB_PROT_Msk (0x7u << DMAC_CFG_AHB_PROT_Pos) /**< \brief (DMAC_CFG) AHB Protection */
#define DMAC_CFG_AHB_PROT(value) ((DMAC_CFG_AHB_PROT_Msk & ((value) << DMAC_CFG_AHB_PROT_Pos)))
#define DMAC_CFG_FIFOCFG_Pos 28
#define DMAC_CFG_FIFOCFG_Msk (0x3u << DMAC_CFG_FIFOCFG_Pos) /**< \brief (DMAC_CFG) FIFO Configuration */
#define DMAC_CFG_FIFOCFG_ALAP_CFG (0x0u << 28) /**< \brief (DMAC_CFG) The largest defined length AHB burst is performed on the destination AHB interface. */
#define DMAC_CFG_FIFOCFG_HALF_CFG (0x1u << 28) /**< \brief (DMAC_CFG) When half FIFO size is available/filled, a source/destination request is serviced. */
#define DMAC_CFG_FIFOCFG_ASAP_CFG (0x2u << 28) /**< \brief (DMAC_CFG) When there is enough space/data available to perform a single AHB access, then the request is serviced. */
/* -------- DMAC_WPMR : (DMAC Offset: 0x1E4) DMAC Write Protect Mode Register -------- */
#define DMAC_WPMR_WPEN (0x1u << 0) /**< \brief (DMAC_WPMR) Write Protect Enable */
#define DMAC_WPMR_WPKEY_Pos 8
#define DMAC_WPMR_WPKEY_Msk (0xffffffu << DMAC_WPMR_WPKEY_Pos) /**< \brief (DMAC_WPMR) Write Protect KEY */
#define DMAC_WPMR_WPKEY(value) ((DMAC_WPMR_WPKEY_Msk & ((value) << DMAC_WPMR_WPKEY_Pos)))
/* -------- DMAC_WPSR : (DMAC Offset: 0x1E8) DMAC Write Protect Status Register -------- */
#define DMAC_WPSR_WPVS (0x1u << 0) /**< \brief (DMAC_WPSR) Write Protect Violation Status */
#define DMAC_WPSR_WPVSRC_Pos 8
#define DMAC_WPSR_WPVSRC_Msk (0xffffu << DMAC_WPSR_WPVSRC_Pos) /**< \brief (DMAC_WPSR) Write Protect Violation Source */
/*@}*/
#endif /* _SAM3XA_DMAC_COMPONENT_ */

View File

@@ -0,0 +1,76 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2012, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _SAM3XA_EFC_COMPONENT_
#define _SAM3XA_EFC_COMPONENT_
/* ============================================================================= */
/** SOFTWARE API DEFINITION FOR Embedded Flash Controller */
/* ============================================================================= */
/** \addtogroup SAM3XA_EFC Embedded Flash Controller */
/*@{*/
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
/** \brief Efc hardware registers */
typedef struct {
RwReg EEFC_FMR; /**< \brief (Efc Offset: 0x00) EEFC Flash Mode Register */
WoReg EEFC_FCR; /**< \brief (Efc Offset: 0x04) EEFC Flash Command Register */
RoReg EEFC_FSR; /**< \brief (Efc Offset: 0x08) EEFC Flash Status Register */
RoReg EEFC_FRR; /**< \brief (Efc Offset: 0x0C) EEFC Flash Result Register */
} Efc;
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
/* -------- EEFC_FMR : (EFC Offset: 0x00) EEFC Flash Mode Register -------- */
#define EEFC_FMR_FRDY (0x1u << 0) /**< \brief (EEFC_FMR) Ready Interrupt Enable */
#define EEFC_FMR_FWS_Pos 8
#define EEFC_FMR_FWS_Msk (0xfu << EEFC_FMR_FWS_Pos) /**< \brief (EEFC_FMR) Flash Wait State */
#define EEFC_FMR_FWS(value) ((EEFC_FMR_FWS_Msk & ((value) << EEFC_FMR_FWS_Pos)))
#define EEFC_FMR_SCOD (0x1u << 16) /**< \brief (EEFC_FMR) Sequential Code Optimization Disable */
#define EEFC_FMR_FAM (0x1u << 24) /**< \brief (EEFC_FMR) Flash Access Mode */
/* -------- EEFC_FCR : (EFC Offset: 0x04) EEFC Flash Command Register -------- */
#define EEFC_FCR_FCMD_Pos 0
#define EEFC_FCR_FCMD_Msk (0xffu << EEFC_FCR_FCMD_Pos) /**< \brief (EEFC_FCR) Flash Command */
#define EEFC_FCR_FCMD(value) ((EEFC_FCR_FCMD_Msk & ((value) << EEFC_FCR_FCMD_Pos)))
#define EEFC_FCR_FARG_Pos 8
#define EEFC_FCR_FARG_Msk (0xffffu << EEFC_FCR_FARG_Pos) /**< \brief (EEFC_FCR) Flash Command Argument */
#define EEFC_FCR_FARG(value) ((EEFC_FCR_FARG_Msk & ((value) << EEFC_FCR_FARG_Pos)))
#define EEFC_FCR_FKEY_Pos 24
#define EEFC_FCR_FKEY_Msk (0xffu << EEFC_FCR_FKEY_Pos) /**< \brief (EEFC_FCR) Flash Writing Protection Key */
#define EEFC_FCR_FKEY(value) ((EEFC_FCR_FKEY_Msk & ((value) << EEFC_FCR_FKEY_Pos)))
/* -------- EEFC_FSR : (EFC Offset: 0x08) EEFC Flash Status Register -------- */
#define EEFC_FSR_FRDY (0x1u << 0) /**< \brief (EEFC_FSR) Flash Ready Status */
#define EEFC_FSR_FCMDE (0x1u << 1) /**< \brief (EEFC_FSR) Flash Command Error Status */
#define EEFC_FSR_FLOCKE (0x1u << 2) /**< \brief (EEFC_FSR) Flash Lock Error Status */
/* -------- EEFC_FRR : (EFC Offset: 0x0C) EEFC Flash Result Register -------- */
#define EEFC_FRR_FVALUE_Pos 0
#define EEFC_FRR_FVALUE_Msk (0xffffffffu << EEFC_FRR_FVALUE_Pos) /**< \brief (EEFC_FRR) Flash Result Value */
/*@}*/
#endif /* _SAM3XA_EFC_COMPONENT_ */

View File

@@ -0,0 +1,335 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2012, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _SAM3XA_EMAC_COMPONENT_
#define _SAM3XA_EMAC_COMPONENT_
/* ============================================================================= */
/** SOFTWARE API DEFINITION FOR Ethernet MAC 10/100 */
/* ============================================================================= */
/** \addtogroup SAM3XA_EMAC Ethernet MAC 10/100 */
/*@{*/
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
/** \brief EmacSa hardware registers */
typedef struct {
RwReg EMAC_SAxB; /**< \brief (EmacSa Offset: 0x0) Specific Address 1 Bottom Register */
RwReg EMAC_SAxT; /**< \brief (EmacSa Offset: 0x4) Specific Address 1 Top Register */
} EmacSa;
/** \brief Emac hardware registers */
#define EMACSA_NUMBER 4
typedef struct {
RwReg EMAC_NCR; /**< \brief (Emac Offset: 0x00) Network Control Register */
RwReg EMAC_NCFGR; /**< \brief (Emac Offset: 0x04) Network Configuration Register */
RoReg EMAC_NSR; /**< \brief (Emac Offset: 0x08) Network Status Register */
RoReg Reserved1[2];
RwReg EMAC_TSR; /**< \brief (Emac Offset: 0x14) Transmit Status Register */
RwReg EMAC_RBQP; /**< \brief (Emac Offset: 0x18) Receive Buffer Queue Pointer Register */
RwReg EMAC_TBQP; /**< \brief (Emac Offset: 0x1C) Transmit Buffer Queue Pointer Register */
RwReg EMAC_RSR; /**< \brief (Emac Offset: 0x20) Receive Status Register */
RwReg EMAC_ISR; /**< \brief (Emac Offset: 0x24) Interrupt Status Register */
WoReg EMAC_IER; /**< \brief (Emac Offset: 0x28) Interrupt Enable Register */
WoReg EMAC_IDR; /**< \brief (Emac Offset: 0x2C) Interrupt Disable Register */
RoReg EMAC_IMR; /**< \brief (Emac Offset: 0x30) Interrupt Mask Register */
RwReg EMAC_MAN; /**< \brief (Emac Offset: 0x34) Phy Maintenance Register */
RwReg EMAC_PTR; /**< \brief (Emac Offset: 0x38) Pause Time Register */
RwReg EMAC_PFR; /**< \brief (Emac Offset: 0x3C) Pause Frames Received Register */
RwReg EMAC_FTO; /**< \brief (Emac Offset: 0x40) Frames Transmitted Ok Register */
RwReg EMAC_SCF; /**< \brief (Emac Offset: 0x44) Single Collision Frames Register */
RwReg EMAC_MCF; /**< \brief (Emac Offset: 0x48) Multiple Collision Frames Register */
RwReg EMAC_FRO; /**< \brief (Emac Offset: 0x4C) Frames Received Ok Register */
RwReg EMAC_FCSE; /**< \brief (Emac Offset: 0x50) Frame Check Sequence Errors Register */
RwReg EMAC_ALE; /**< \brief (Emac Offset: 0x54) Alignment Errors Register */
RwReg EMAC_DTF; /**< \brief (Emac Offset: 0x58) Deferred Transmission Frames Register */
RwReg EMAC_LCOL; /**< \brief (Emac Offset: 0x5C) Late Collisions Register */
RwReg EMAC_ECOL; /**< \brief (Emac Offset: 0x60) Excessive Collisions Register */
RwReg EMAC_TUND; /**< \brief (Emac Offset: 0x64) Transmit Underrun Errors Register */
RwReg EMAC_CSE; /**< \brief (Emac Offset: 0x68) Carrier Sense Errors Register */
RwReg EMAC_RRE; /**< \brief (Emac Offset: 0x6C) Receive Resource Errors Register */
RwReg EMAC_ROV; /**< \brief (Emac Offset: 0x70) Receive Overrun Errors Register */
RwReg EMAC_RSE; /**< \brief (Emac Offset: 0x74) Receive Symbol Errors Register */
RwReg EMAC_ELE; /**< \brief (Emac Offset: 0x78) Excessive Length Errors Register */
RwReg EMAC_RJA; /**< \brief (Emac Offset: 0x7C) Receive Jabbers Register */
RwReg EMAC_USF; /**< \brief (Emac Offset: 0x80) Undersize Frames Register */
RwReg EMAC_STE; /**< \brief (Emac Offset: 0x84) SQE Test Errors Register */
RwReg EMAC_RLE; /**< \brief (Emac Offset: 0x88) Received Length Field Mismatch Register */
RoReg Reserved2[1];
RwReg EMAC_HRB; /**< \brief (Emac Offset: 0x90) Hash Register Bottom [31:0] Register */
RwReg EMAC_HRT; /**< \brief (Emac Offset: 0x94) Hash Register Top [63:32] Register */
EmacSa EMAC_SA[EMACSA_NUMBER]; /**< \brief (Emac Offset: 0x98) sa = 1 .. 4 */
RwReg EMAC_TID; /**< \brief (Emac Offset: 0xB8) Type ID Checking Register */
RoReg Reserved3[1];
RwReg EMAC_USRIO; /**< \brief (Emac Offset: 0xC0) User Input/Output Register */
} Emac;
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
/* -------- EMAC_NCR : (EMAC Offset: 0x00) Network Control Register -------- */
#define EMAC_NCR_LB (0x1u << 0) /**< \brief (EMAC_NCR) LoopBack */
#define EMAC_NCR_LLB (0x1u << 1) /**< \brief (EMAC_NCR) Loopback local */
#define EMAC_NCR_RE (0x1u << 2) /**< \brief (EMAC_NCR) Receive enable */
#define EMAC_NCR_TE (0x1u << 3) /**< \brief (EMAC_NCR) Transmit enable */
#define EMAC_NCR_MPE (0x1u << 4) /**< \brief (EMAC_NCR) Management port enable */
#define EMAC_NCR_CLRSTAT (0x1u << 5) /**< \brief (EMAC_NCR) Clear statistics registers */
#define EMAC_NCR_INCSTAT (0x1u << 6) /**< \brief (EMAC_NCR) Increment statistics registers */
#define EMAC_NCR_WESTAT (0x1u << 7) /**< \brief (EMAC_NCR) Write enable for statistics registers */
#define EMAC_NCR_BP (0x1u << 8) /**< \brief (EMAC_NCR) Back pressure */
#define EMAC_NCR_TSTART (0x1u << 9) /**< \brief (EMAC_NCR) Start transmission */
#define EMAC_NCR_THALT (0x1u << 10) /**< \brief (EMAC_NCR) Transmit halt */
/* -------- EMAC_NCFGR : (EMAC Offset: 0x04) Network Configuration Register -------- */
#define EMAC_NCFGR_SPD (0x1u << 0) /**< \brief (EMAC_NCFGR) Speed */
#define EMAC_NCFGR_FD (0x1u << 1) /**< \brief (EMAC_NCFGR) Full Duplex */
#define EMAC_NCFGR_JFRAME (0x1u << 3) /**< \brief (EMAC_NCFGR) Jumbo Frames */
#define EMAC_NCFGR_CAF (0x1u << 4) /**< \brief (EMAC_NCFGR) Copy All Frames */
#define EMAC_NCFGR_NBC (0x1u << 5) /**< \brief (EMAC_NCFGR) No Broadcast */
#define EMAC_NCFGR_MTI (0x1u << 6) /**< \brief (EMAC_NCFGR) Multicast Hash Enable */
#define EMAC_NCFGR_UNI (0x1u << 7) /**< \brief (EMAC_NCFGR) Unicast Hash Enable */
#define EMAC_NCFGR_BIG (0x1u << 8) /**< \brief (EMAC_NCFGR) Receive 1536 bytes frames */
#define EMAC_NCFGR_CLK_Pos 10
#define EMAC_NCFGR_CLK_Msk (0x3u << EMAC_NCFGR_CLK_Pos) /**< \brief (EMAC_NCFGR) MDC clock divider */
#define EMAC_NCFGR_CLK_MCK_8 (0x0u << 10) /**< \brief (EMAC_NCFGR) MCK divided by 8 (MCK up to 20 MHz). */
#define EMAC_NCFGR_CLK_MCK_16 (0x1u << 10) /**< \brief (EMAC_NCFGR) MCK divided by 16 (MCK up to 40 MHz). */
#define EMAC_NCFGR_CLK_MCK_32 (0x2u << 10) /**< \brief (EMAC_NCFGR) MCK divided by 32 (MCK up to 80 MHz). */
#define EMAC_NCFGR_CLK_MCK_64 (0x3u << 10) /**< \brief (EMAC_NCFGR) MCK divided by 64 (MCK up to 160 MHz). */
#define EMAC_NCFGR_RTY (0x1u << 12) /**< \brief (EMAC_NCFGR) Retry test */
#define EMAC_NCFGR_PAE (0x1u << 13) /**< \brief (EMAC_NCFGR) Pause Enable */
#define EMAC_NCFGR_RBOF_Pos 14
#define EMAC_NCFGR_RBOF_Msk (0x3u << EMAC_NCFGR_RBOF_Pos) /**< \brief (EMAC_NCFGR) Receive Buffer Offset */
#define EMAC_NCFGR_RBOF_OFFSET_0 (0x0u << 14) /**< \brief (EMAC_NCFGR) No offset from start of receive buffer. */
#define EMAC_NCFGR_RBOF_OFFSET_1 (0x1u << 14) /**< \brief (EMAC_NCFGR) One-byte offset from start of receive buffer. */
#define EMAC_NCFGR_RBOF_OFFSET_2 (0x2u << 14) /**< \brief (EMAC_NCFGR) Two-byte offset from start of receive buffer. */
#define EMAC_NCFGR_RBOF_OFFSET_3 (0x3u << 14) /**< \brief (EMAC_NCFGR) Three-byte offset from start of receive buffer. */
#define EMAC_NCFGR_RLCE (0x1u << 16) /**< \brief (EMAC_NCFGR) Receive Length field Checking Enable */
#define EMAC_NCFGR_DRFCS (0x1u << 17) /**< \brief (EMAC_NCFGR) Discard Receive FCS */
#define EMAC_NCFGR_EFRHD (0x1u << 18) /**< \brief (EMAC_NCFGR) */
#define EMAC_NCFGR_IRXFCS (0x1u << 19) /**< \brief (EMAC_NCFGR) Ignore RX FCS */
/* -------- EMAC_NSR : (EMAC Offset: 0x08) Network Status Register -------- */
#define EMAC_NSR_MDIO (0x1u << 1) /**< \brief (EMAC_NSR) */
#define EMAC_NSR_IDLE (0x1u << 2) /**< \brief (EMAC_NSR) */
/* -------- EMAC_TSR : (EMAC Offset: 0x14) Transmit Status Register -------- */
#define EMAC_TSR_UBR (0x1u << 0) /**< \brief (EMAC_TSR) Used Bit Read */
#define EMAC_TSR_COL (0x1u << 1) /**< \brief (EMAC_TSR) Collision Occurred */
#define EMAC_TSR_RLES (0x1u << 2) /**< \brief (EMAC_TSR) Retry Limit exceeded */
#define EMAC_TSR_TGO (0x1u << 3) /**< \brief (EMAC_TSR) Transmit Go */
#define EMAC_TSR_BEX (0x1u << 4) /**< \brief (EMAC_TSR) Buffers exhausted mid frame */
#define EMAC_TSR_COMP (0x1u << 5) /**< \brief (EMAC_TSR) Transmit Complete */
#define EMAC_TSR_UND (0x1u << 6) /**< \brief (EMAC_TSR) Transmit Underrun */
/* -------- EMAC_RBQP : (EMAC Offset: 0x18) Receive Buffer Queue Pointer Register -------- */
#define EMAC_RBQP_ADDR_Pos 2
#define EMAC_RBQP_ADDR_Msk (0x3fffffffu << EMAC_RBQP_ADDR_Pos) /**< \brief (EMAC_RBQP) Receive buffer queue pointer address */
#define EMAC_RBQP_ADDR(value) ((EMAC_RBQP_ADDR_Msk & ((value) << EMAC_RBQP_ADDR_Pos)))
/* -------- EMAC_TBQP : (EMAC Offset: 0x1C) Transmit Buffer Queue Pointer Register -------- */
#define EMAC_TBQP_ADDR_Pos 2
#define EMAC_TBQP_ADDR_Msk (0x3fffffffu << EMAC_TBQP_ADDR_Pos) /**< \brief (EMAC_TBQP) Transmit buffer queue pointer address */
#define EMAC_TBQP_ADDR(value) ((EMAC_TBQP_ADDR_Msk & ((value) << EMAC_TBQP_ADDR_Pos)))
/* -------- EMAC_RSR : (EMAC Offset: 0x20) Receive Status Register -------- */
#define EMAC_RSR_BNA (0x1u << 0) /**< \brief (EMAC_RSR) Buffer Not Available */
#define EMAC_RSR_REC (0x1u << 1) /**< \brief (EMAC_RSR) Frame Received */
#define EMAC_RSR_OVR (0x1u << 2) /**< \brief (EMAC_RSR) Receive Overrun */
/* -------- EMAC_ISR : (EMAC Offset: 0x24) Interrupt Status Register -------- */
#define EMAC_ISR_MFD (0x1u << 0) /**< \brief (EMAC_ISR) Management Frame Done */
#define EMAC_ISR_RCOMP (0x1u << 1) /**< \brief (EMAC_ISR) Receive Complete */
#define EMAC_ISR_RXUBR (0x1u << 2) /**< \brief (EMAC_ISR) Receive Used Bit Read */
#define EMAC_ISR_TXUBR (0x1u << 3) /**< \brief (EMAC_ISR) Transmit Used Bit Read */
#define EMAC_ISR_TUND (0x1u << 4) /**< \brief (EMAC_ISR) Ethernet Transmit Buffer Underrun */
#define EMAC_ISR_RLEX (0x1u << 5) /**< \brief (EMAC_ISR) Retry Limit Exceeded */
#define EMAC_ISR_TXERR (0x1u << 6) /**< \brief (EMAC_ISR) Transmit Error */
#define EMAC_ISR_TCOMP (0x1u << 7) /**< \brief (EMAC_ISR) Transmit Complete */
#define EMAC_ISR_ROVR (0x1u << 10) /**< \brief (EMAC_ISR) Receive Overrun */
#define EMAC_ISR_HRESP (0x1u << 11) /**< \brief (EMAC_ISR) Hresp not OK */
#define EMAC_ISR_PFRE (0x1u << 12) /**< \brief (EMAC_ISR) Pause Frame Received */
#define EMAC_ISR_PTZ (0x1u << 13) /**< \brief (EMAC_ISR) Pause Time Zero */
/* -------- EMAC_IER : (EMAC Offset: 0x28) Interrupt Enable Register -------- */
#define EMAC_IER_MFD (0x1u << 0) /**< \brief (EMAC_IER) Management Frame sent */
#define EMAC_IER_RCOMP (0x1u << 1) /**< \brief (EMAC_IER) Receive Complete */
#define EMAC_IER_RXUBR (0x1u << 2) /**< \brief (EMAC_IER) Receive Used Bit Read */
#define EMAC_IER_TXUBR (0x1u << 3) /**< \brief (EMAC_IER) Transmit Used Bit Read */
#define EMAC_IER_TUND (0x1u << 4) /**< \brief (EMAC_IER) Ethernet Transmit Buffer Underrun */
#define EMAC_IER_RLE (0x1u << 5) /**< \brief (EMAC_IER) Retry Limit Exceeded */
#define EMAC_IER_TXERR (0x1u << 6) /**< \brief (EMAC_IER) */
#define EMAC_IER_TCOMP (0x1u << 7) /**< \brief (EMAC_IER) Transmit Complete */
#define EMAC_IER_ROVR (0x1u << 10) /**< \brief (EMAC_IER) Receive Overrun */
#define EMAC_IER_HRESP (0x1u << 11) /**< \brief (EMAC_IER) Hresp not OK */
#define EMAC_IER_PFR (0x1u << 12) /**< \brief (EMAC_IER) Pause Frame Received */
#define EMAC_IER_PTZ (0x1u << 13) /**< \brief (EMAC_IER) Pause Time Zero */
/* -------- EMAC_IDR : (EMAC Offset: 0x2C) Interrupt Disable Register -------- */
#define EMAC_IDR_MFD (0x1u << 0) /**< \brief (EMAC_IDR) Management Frame sent */
#define EMAC_IDR_RCOMP (0x1u << 1) /**< \brief (EMAC_IDR) Receive Complete */
#define EMAC_IDR_RXUBR (0x1u << 2) /**< \brief (EMAC_IDR) Receive Used Bit Read */
#define EMAC_IDR_TXUBR (0x1u << 3) /**< \brief (EMAC_IDR) Transmit Used Bit Read */
#define EMAC_IDR_TUND (0x1u << 4) /**< \brief (EMAC_IDR) Ethernet Transmit Buffer Underrun */
#define EMAC_IDR_RLE (0x1u << 5) /**< \brief (EMAC_IDR) Retry Limit Exceeded */
#define EMAC_IDR_TXERR (0x1u << 6) /**< \brief (EMAC_IDR) */
#define EMAC_IDR_TCOMP (0x1u << 7) /**< \brief (EMAC_IDR) Transmit Complete */
#define EMAC_IDR_ROVR (0x1u << 10) /**< \brief (EMAC_IDR) Receive Overrun */
#define EMAC_IDR_HRESP (0x1u << 11) /**< \brief (EMAC_IDR) Hresp not OK */
#define EMAC_IDR_PFR (0x1u << 12) /**< \brief (EMAC_IDR) Pause Frame Received */
#define EMAC_IDR_PTZ (0x1u << 13) /**< \brief (EMAC_IDR) Pause Time Zero */
/* -------- EMAC_IMR : (EMAC Offset: 0x30) Interrupt Mask Register -------- */
#define EMAC_IMR_MFD (0x1u << 0) /**< \brief (EMAC_IMR) Management Frame sent */
#define EMAC_IMR_RCOMP (0x1u << 1) /**< \brief (EMAC_IMR) Receive Complete */
#define EMAC_IMR_RXUBR (0x1u << 2) /**< \brief (EMAC_IMR) Receive Used Bit Read */
#define EMAC_IMR_TXUBR (0x1u << 3) /**< \brief (EMAC_IMR) Transmit Used Bit Read */
#define EMAC_IMR_TUND (0x1u << 4) /**< \brief (EMAC_IMR) Ethernet Transmit Buffer Underrun */
#define EMAC_IMR_RLE (0x1u << 5) /**< \brief (EMAC_IMR) Retry Limit Exceeded */
#define EMAC_IMR_TXERR (0x1u << 6) /**< \brief (EMAC_IMR) */
#define EMAC_IMR_TCOMP (0x1u << 7) /**< \brief (EMAC_IMR) Transmit Complete */
#define EMAC_IMR_ROVR (0x1u << 10) /**< \brief (EMAC_IMR) Receive Overrun */
#define EMAC_IMR_HRESP (0x1u << 11) /**< \brief (EMAC_IMR) Hresp not OK */
#define EMAC_IMR_PFR (0x1u << 12) /**< \brief (EMAC_IMR) Pause Frame Received */
#define EMAC_IMR_PTZ (0x1u << 13) /**< \brief (EMAC_IMR) Pause Time Zero */
/* -------- EMAC_MAN : (EMAC Offset: 0x34) Phy Maintenance Register -------- */
#define EMAC_MAN_DATA_Pos 0
#define EMAC_MAN_DATA_Msk (0xffffu << EMAC_MAN_DATA_Pos) /**< \brief (EMAC_MAN) */
#define EMAC_MAN_DATA(value) ((EMAC_MAN_DATA_Msk & ((value) << EMAC_MAN_DATA_Pos)))
#define EMAC_MAN_CODE_Pos 16
#define EMAC_MAN_CODE_Msk (0x3u << EMAC_MAN_CODE_Pos) /**< \brief (EMAC_MAN) */
#define EMAC_MAN_CODE(value) ((EMAC_MAN_CODE_Msk & ((value) << EMAC_MAN_CODE_Pos)))
#define EMAC_MAN_REGA_Pos 18
#define EMAC_MAN_REGA_Msk (0x1fu << EMAC_MAN_REGA_Pos) /**< \brief (EMAC_MAN) Register Address */
#define EMAC_MAN_REGA(value) ((EMAC_MAN_REGA_Msk & ((value) << EMAC_MAN_REGA_Pos)))
#define EMAC_MAN_PHYA_Pos 23
#define EMAC_MAN_PHYA_Msk (0x1fu << EMAC_MAN_PHYA_Pos) /**< \brief (EMAC_MAN) PHY Address */
#define EMAC_MAN_PHYA(value) ((EMAC_MAN_PHYA_Msk & ((value) << EMAC_MAN_PHYA_Pos)))
#define EMAC_MAN_RW_Pos 28
#define EMAC_MAN_RW_Msk (0x3u << EMAC_MAN_RW_Pos) /**< \brief (EMAC_MAN) Read-write */
#define EMAC_MAN_RW(value) ((EMAC_MAN_RW_Msk & ((value) << EMAC_MAN_RW_Pos)))
#define EMAC_MAN_SOF_Pos 30
#define EMAC_MAN_SOF_Msk (0x3u << EMAC_MAN_SOF_Pos) /**< \brief (EMAC_MAN) Start of frame */
#define EMAC_MAN_SOF(value) ((EMAC_MAN_SOF_Msk & ((value) << EMAC_MAN_SOF_Pos)))
/* -------- EMAC_PTR : (EMAC Offset: 0x38) Pause Time Register -------- */
#define EMAC_PTR_PTIME_Pos 0
#define EMAC_PTR_PTIME_Msk (0xffffu << EMAC_PTR_PTIME_Pos) /**< \brief (EMAC_PTR) Pause Time */
#define EMAC_PTR_PTIME(value) ((EMAC_PTR_PTIME_Msk & ((value) << EMAC_PTR_PTIME_Pos)))
/* -------- EMAC_PFR : (EMAC Offset: 0x3C) Pause Frames Received Register -------- */
#define EMAC_PFR_FROK_Pos 0
#define EMAC_PFR_FROK_Msk (0xffffu << EMAC_PFR_FROK_Pos) /**< \brief (EMAC_PFR) Pause Frames received OK */
#define EMAC_PFR_FROK(value) ((EMAC_PFR_FROK_Msk & ((value) << EMAC_PFR_FROK_Pos)))
/* -------- EMAC_FTO : (EMAC Offset: 0x40) Frames Transmitted Ok Register -------- */
#define EMAC_FTO_FTOK_Pos 0
#define EMAC_FTO_FTOK_Msk (0xffffffu << EMAC_FTO_FTOK_Pos) /**< \brief (EMAC_FTO) Frames Transmitted OK */
#define EMAC_FTO_FTOK(value) ((EMAC_FTO_FTOK_Msk & ((value) << EMAC_FTO_FTOK_Pos)))
/* -------- EMAC_SCF : (EMAC Offset: 0x44) Single Collision Frames Register -------- */
#define EMAC_SCF_SCF_Pos 0
#define EMAC_SCF_SCF_Msk (0xffffu << EMAC_SCF_SCF_Pos) /**< \brief (EMAC_SCF) Single Collision Frames */
#define EMAC_SCF_SCF(value) ((EMAC_SCF_SCF_Msk & ((value) << EMAC_SCF_SCF_Pos)))
/* -------- EMAC_MCF : (EMAC Offset: 0x48) Multiple Collision Frames Register -------- */
#define EMAC_MCF_MCF_Pos 0
#define EMAC_MCF_MCF_Msk (0xffffu << EMAC_MCF_MCF_Pos) /**< \brief (EMAC_MCF) Multicollision Frames */
#define EMAC_MCF_MCF(value) ((EMAC_MCF_MCF_Msk & ((value) << EMAC_MCF_MCF_Pos)))
/* -------- EMAC_FRO : (EMAC Offset: 0x4C) Frames Received Ok Register -------- */
#define EMAC_FRO_FROK_Pos 0
#define EMAC_FRO_FROK_Msk (0xffffffu << EMAC_FRO_FROK_Pos) /**< \brief (EMAC_FRO) Frames Received OK */
#define EMAC_FRO_FROK(value) ((EMAC_FRO_FROK_Msk & ((value) << EMAC_FRO_FROK_Pos)))
/* -------- EMAC_FCSE : (EMAC Offset: 0x50) Frame Check Sequence Errors Register -------- */
#define EMAC_FCSE_FCSE_Pos 0
#define EMAC_FCSE_FCSE_Msk (0xffu << EMAC_FCSE_FCSE_Pos) /**< \brief (EMAC_FCSE) Frame Check Sequence Errors */
#define EMAC_FCSE_FCSE(value) ((EMAC_FCSE_FCSE_Msk & ((value) << EMAC_FCSE_FCSE_Pos)))
/* -------- EMAC_ALE : (EMAC Offset: 0x54) Alignment Errors Register -------- */
#define EMAC_ALE_ALE_Pos 0
#define EMAC_ALE_ALE_Msk (0xffu << EMAC_ALE_ALE_Pos) /**< \brief (EMAC_ALE) Alignment Errors */
#define EMAC_ALE_ALE(value) ((EMAC_ALE_ALE_Msk & ((value) << EMAC_ALE_ALE_Pos)))
/* -------- EMAC_DTF : (EMAC Offset: 0x58) Deferred Transmission Frames Register -------- */
#define EMAC_DTF_DTF_Pos 0
#define EMAC_DTF_DTF_Msk (0xffffu << EMAC_DTF_DTF_Pos) /**< \brief (EMAC_DTF) Deferred Transmission Frames */
#define EMAC_DTF_DTF(value) ((EMAC_DTF_DTF_Msk & ((value) << EMAC_DTF_DTF_Pos)))
/* -------- EMAC_LCOL : (EMAC Offset: 0x5C) Late Collisions Register -------- */
#define EMAC_LCOL_LCOL_Pos 0
#define EMAC_LCOL_LCOL_Msk (0xffu << EMAC_LCOL_LCOL_Pos) /**< \brief (EMAC_LCOL) Late Collisions */
#define EMAC_LCOL_LCOL(value) ((EMAC_LCOL_LCOL_Msk & ((value) << EMAC_LCOL_LCOL_Pos)))
/* -------- EMAC_ECOL : (EMAC Offset: 0x60) Excessive Collisions Register -------- */
#define EMAC_ECOL_EXCOL_Pos 0
#define EMAC_ECOL_EXCOL_Msk (0xffu << EMAC_ECOL_EXCOL_Pos) /**< \brief (EMAC_ECOL) Excessive Collisions */
#define EMAC_ECOL_EXCOL(value) ((EMAC_ECOL_EXCOL_Msk & ((value) << EMAC_ECOL_EXCOL_Pos)))
/* -------- EMAC_TUND : (EMAC Offset: 0x64) Transmit Underrun Errors Register -------- */
#define EMAC_TUND_TUND_Pos 0
#define EMAC_TUND_TUND_Msk (0xffu << EMAC_TUND_TUND_Pos) /**< \brief (EMAC_TUND) Transmit Underruns */
#define EMAC_TUND_TUND(value) ((EMAC_TUND_TUND_Msk & ((value) << EMAC_TUND_TUND_Pos)))
/* -------- EMAC_CSE : (EMAC Offset: 0x68) Carrier Sense Errors Register -------- */
#define EMAC_CSE_CSE_Pos 0
#define EMAC_CSE_CSE_Msk (0xffu << EMAC_CSE_CSE_Pos) /**< \brief (EMAC_CSE) Carrier Sense Errors */
#define EMAC_CSE_CSE(value) ((EMAC_CSE_CSE_Msk & ((value) << EMAC_CSE_CSE_Pos)))
/* -------- EMAC_RRE : (EMAC Offset: 0x6C) Receive Resource Errors Register -------- */
#define EMAC_RRE_RRE_Pos 0
#define EMAC_RRE_RRE_Msk (0xffffu << EMAC_RRE_RRE_Pos) /**< \brief (EMAC_RRE) Receive Resource Errors */
#define EMAC_RRE_RRE(value) ((EMAC_RRE_RRE_Msk & ((value) << EMAC_RRE_RRE_Pos)))
/* -------- EMAC_ROV : (EMAC Offset: 0x70) Receive Overrun Errors Register -------- */
#define EMAC_ROV_ROVR_Pos 0
#define EMAC_ROV_ROVR_Msk (0xffu << EMAC_ROV_ROVR_Pos) /**< \brief (EMAC_ROV) Receive Overrun */
#define EMAC_ROV_ROVR(value) ((EMAC_ROV_ROVR_Msk & ((value) << EMAC_ROV_ROVR_Pos)))
/* -------- EMAC_RSE : (EMAC Offset: 0x74) Receive Symbol Errors Register -------- */
#define EMAC_RSE_RSE_Pos 0
#define EMAC_RSE_RSE_Msk (0xffu << EMAC_RSE_RSE_Pos) /**< \brief (EMAC_RSE) Receive Symbol Errors */
#define EMAC_RSE_RSE(value) ((EMAC_RSE_RSE_Msk & ((value) << EMAC_RSE_RSE_Pos)))
/* -------- EMAC_ELE : (EMAC Offset: 0x78) Excessive Length Errors Register -------- */
#define EMAC_ELE_EXL_Pos 0
#define EMAC_ELE_EXL_Msk (0xffu << EMAC_ELE_EXL_Pos) /**< \brief (EMAC_ELE) Excessive Length Errors */
#define EMAC_ELE_EXL(value) ((EMAC_ELE_EXL_Msk & ((value) << EMAC_ELE_EXL_Pos)))
/* -------- EMAC_RJA : (EMAC Offset: 0x7C) Receive Jabbers Register -------- */
#define EMAC_RJA_RJB_Pos 0
#define EMAC_RJA_RJB_Msk (0xffu << EMAC_RJA_RJB_Pos) /**< \brief (EMAC_RJA) Receive Jabbers */
#define EMAC_RJA_RJB(value) ((EMAC_RJA_RJB_Msk & ((value) << EMAC_RJA_RJB_Pos)))
/* -------- EMAC_USF : (EMAC Offset: 0x80) Undersize Frames Register -------- */
#define EMAC_USF_USF_Pos 0
#define EMAC_USF_USF_Msk (0xffu << EMAC_USF_USF_Pos) /**< \brief (EMAC_USF) Undersize frames */
#define EMAC_USF_USF(value) ((EMAC_USF_USF_Msk & ((value) << EMAC_USF_USF_Pos)))
/* -------- EMAC_STE : (EMAC Offset: 0x84) SQE Test Errors Register -------- */
#define EMAC_STE_SQER_Pos 0
#define EMAC_STE_SQER_Msk (0xffu << EMAC_STE_SQER_Pos) /**< \brief (EMAC_STE) SQE test errors */
#define EMAC_STE_SQER(value) ((EMAC_STE_SQER_Msk & ((value) << EMAC_STE_SQER_Pos)))
/* -------- EMAC_RLE : (EMAC Offset: 0x88) Received Length Field Mismatch Register -------- */
#define EMAC_RLE_RLFM_Pos 0
#define EMAC_RLE_RLFM_Msk (0xffu << EMAC_RLE_RLFM_Pos) /**< \brief (EMAC_RLE) Receive Length Field Mismatch */
#define EMAC_RLE_RLFM(value) ((EMAC_RLE_RLFM_Msk & ((value) << EMAC_RLE_RLFM_Pos)))
/* -------- EMAC_HRB : (EMAC Offset: 0x90) Hash Register Bottom [31:0] Register -------- */
#define EMAC_HRB_ADDR_Pos 0
#define EMAC_HRB_ADDR_Msk (0xffffffffu << EMAC_HRB_ADDR_Pos) /**< \brief (EMAC_HRB) */
#define EMAC_HRB_ADDR(value) ((EMAC_HRB_ADDR_Msk & ((value) << EMAC_HRB_ADDR_Pos)))
/* -------- EMAC_HRT : (EMAC Offset: 0x94) Hash Register Top [63:32] Register -------- */
#define EMAC_HRT_ADDR_Pos 0
#define EMAC_HRT_ADDR_Msk (0xffffffffu << EMAC_HRT_ADDR_Pos) /**< \brief (EMAC_HRT) */
#define EMAC_HRT_ADDR(value) ((EMAC_HRT_ADDR_Msk & ((value) << EMAC_HRT_ADDR_Pos)))
/* -------- EMAC_SAxB : (EMAC Offset: N/A) Specific Address 1 Bottom Register -------- */
#define EMAC_SAxB_ADDR_Pos 0
#define EMAC_SAxB_ADDR_Msk (0xffffffffu << EMAC_SAxB_ADDR_Pos) /**< \brief (EMAC_SAxB) */
#define EMAC_SAxB_ADDR(value) ((EMAC_SAxB_ADDR_Msk & ((value) << EMAC_SAxB_ADDR_Pos)))
/* -------- EMAC_SAxT : (EMAC Offset: N/A) Specific Address 1 Top Register -------- */
#define EMAC_SAxT_ADDR_Pos 0
#define EMAC_SAxT_ADDR_Msk (0xffffu << EMAC_SAxT_ADDR_Pos) /**< \brief (EMAC_SAxT) */
#define EMAC_SAxT_ADDR(value) ((EMAC_SAxT_ADDR_Msk & ((value) << EMAC_SAxT_ADDR_Pos)))
/* -------- EMAC_TID : (EMAC Offset: 0xB8) Type ID Checking Register -------- */
#define EMAC_TID_TID_Pos 0
#define EMAC_TID_TID_Msk (0xffffu << EMAC_TID_TID_Pos) /**< \brief (EMAC_TID) Type ID checking */
#define EMAC_TID_TID(value) ((EMAC_TID_TID_Msk & ((value) << EMAC_TID_TID_Pos)))
/* -------- EMAC_USRIO : (EMAC Offset: 0xC0) User Input/Output Register -------- */
#define EMAC_USRIO_RMII (0x1u << 0) /**< \brief (EMAC_USRIO) Reduce MII */
#define EMAC_USRIO_CLKEN (0x1u << 1) /**< \brief (EMAC_USRIO) Clock Enable */
/*@}*/
#endif /* _SAM3XA_EMAC_COMPONENT_ */

View File

@@ -0,0 +1,53 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2012, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _SAM3XA_GPBR_COMPONENT_
#define _SAM3XA_GPBR_COMPONENT_
/* ============================================================================= */
/** SOFTWARE API DEFINITION FOR General Purpose Backup Register */
/* ============================================================================= */
/** \addtogroup SAM3XA_GPBR General Purpose Backup Register */
/*@{*/
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
/** \brief Gpbr hardware registers */
typedef struct {
RwReg SYS_GPBR[8]; /**< \brief (Gpbr Offset: 0x0) General Purpose Backup Register */
} Gpbr;
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
/* -------- SYS_GPBR[8] : (GPBR Offset: 0x0) General Purpose Backup Register -------- */
#define SYS_GPBR_GPBR_VALUE_Pos 0
#define SYS_GPBR_GPBR_VALUE_Msk (0xffffffffu << SYS_GPBR_GPBR_VALUE_Pos) /**< \brief (SYS_GPBR[8]) Value of GPBR x */
#define SYS_GPBR_GPBR_VALUE(value) ((SYS_GPBR_GPBR_VALUE_Msk & ((value) << SYS_GPBR_GPBR_VALUE_Pos)))
/*@}*/
#endif /* _SAM3XA_GPBR_COMPONENT_ */

View File

@@ -0,0 +1,341 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2012, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _SAM3XA_HSMCI_COMPONENT_
#define _SAM3XA_HSMCI_COMPONENT_
/* ============================================================================= */
/** SOFTWARE API DEFINITION FOR High Speed MultiMedia Card Interface */
/* ============================================================================= */
/** \addtogroup SAM3XA_HSMCI High Speed MultiMedia Card Interface */
/*@{*/
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
/** \brief Hsmci hardware registers */
typedef struct {
WoReg HSMCI_CR; /**< \brief (Hsmci Offset: 0x00) Control Register */
RwReg HSMCI_MR; /**< \brief (Hsmci Offset: 0x04) Mode Register */
RwReg HSMCI_DTOR; /**< \brief (Hsmci Offset: 0x08) Data Timeout Register */
RwReg HSMCI_SDCR; /**< \brief (Hsmci Offset: 0x0C) SD/SDIO Card Register */
RwReg HSMCI_ARGR; /**< \brief (Hsmci Offset: 0x10) Argument Register */
WoReg HSMCI_CMDR; /**< \brief (Hsmci Offset: 0x14) Command Register */
RwReg HSMCI_BLKR; /**< \brief (Hsmci Offset: 0x18) Block Register */
RwReg HSMCI_CSTOR; /**< \brief (Hsmci Offset: 0x1C) Completion Signal Timeout Register */
RoReg HSMCI_RSPR[4]; /**< \brief (Hsmci Offset: 0x20) Response Register */
RoReg HSMCI_RDR; /**< \brief (Hsmci Offset: 0x30) Receive Data Register */
WoReg HSMCI_TDR; /**< \brief (Hsmci Offset: 0x34) Transmit Data Register */
RoReg Reserved1[2];
RoReg HSMCI_SR; /**< \brief (Hsmci Offset: 0x40) Status Register */
WoReg HSMCI_IER; /**< \brief (Hsmci Offset: 0x44) Interrupt Enable Register */
WoReg HSMCI_IDR; /**< \brief (Hsmci Offset: 0x48) Interrupt Disable Register */
RoReg HSMCI_IMR; /**< \brief (Hsmci Offset: 0x4C) Interrupt Mask Register */
RwReg HSMCI_DMA; /**< \brief (Hsmci Offset: 0x50) DMA Configuration Register */
RwReg HSMCI_CFG; /**< \brief (Hsmci Offset: 0x54) Configuration Register */
RoReg Reserved2[35];
RwReg HSMCI_WPMR; /**< \brief (Hsmci Offset: 0xE4) Write Protection Mode Register */
RoReg HSMCI_WPSR; /**< \brief (Hsmci Offset: 0xE8) Write Protection Status Register */
RoReg Reserved3[69];
RwReg HSMCI_FIFO[256]; /**< \brief (Hsmci Offset: 0x200) FIFO Memory Aperture0 */
} Hsmci;
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
/* -------- HSMCI_CR : (HSMCI Offset: 0x00) Control Register -------- */
#define HSMCI_CR_MCIEN (0x1u << 0) /**< \brief (HSMCI_CR) Multi-Media Interface Enable */
#define HSMCI_CR_MCIDIS (0x1u << 1) /**< \brief (HSMCI_CR) Multi-Media Interface Disable */
#define HSMCI_CR_PWSEN (0x1u << 2) /**< \brief (HSMCI_CR) Power Save Mode Enable */
#define HSMCI_CR_PWSDIS (0x1u << 3) /**< \brief (HSMCI_CR) Power Save Mode Disable */
#define HSMCI_CR_SWRST (0x1u << 7) /**< \brief (HSMCI_CR) Software Reset */
/* -------- HSMCI_MR : (HSMCI Offset: 0x04) Mode Register -------- */
#define HSMCI_MR_CLKDIV_Pos 0
#define HSMCI_MR_CLKDIV_Msk (0xffu << HSMCI_MR_CLKDIV_Pos) /**< \brief (HSMCI_MR) Clock Divider */
#define HSMCI_MR_CLKDIV(value) ((HSMCI_MR_CLKDIV_Msk & ((value) << HSMCI_MR_CLKDIV_Pos)))
#define HSMCI_MR_PWSDIV_Pos 8
#define HSMCI_MR_PWSDIV_Msk (0x7u << HSMCI_MR_PWSDIV_Pos) /**< \brief (HSMCI_MR) Power Saving Divider */
#define HSMCI_MR_PWSDIV(value) ((HSMCI_MR_PWSDIV_Msk & ((value) << HSMCI_MR_PWSDIV_Pos)))
#define HSMCI_MR_RDPROOF (0x1u << 11) /**< \brief (HSMCI_MR) */
#define HSMCI_MR_WRPROOF (0x1u << 12) /**< \brief (HSMCI_MR) */
#define HSMCI_MR_FBYTE (0x1u << 13) /**< \brief (HSMCI_MR) Force Byte Transfer */
#define HSMCI_MR_PADV (0x1u << 14) /**< \brief (HSMCI_MR) Padding Value */
/* -------- HSMCI_DTOR : (HSMCI Offset: 0x08) Data Timeout Register -------- */
#define HSMCI_DTOR_DTOCYC_Pos 0
#define HSMCI_DTOR_DTOCYC_Msk (0xfu << HSMCI_DTOR_DTOCYC_Pos) /**< \brief (HSMCI_DTOR) Data Timeout Cycle Number */
#define HSMCI_DTOR_DTOCYC(value) ((HSMCI_DTOR_DTOCYC_Msk & ((value) << HSMCI_DTOR_DTOCYC_Pos)))
#define HSMCI_DTOR_DTOMUL_Pos 4
#define HSMCI_DTOR_DTOMUL_Msk (0x7u << HSMCI_DTOR_DTOMUL_Pos) /**< \brief (HSMCI_DTOR) Data Timeout Multiplier */
#define HSMCI_DTOR_DTOMUL_1 (0x0u << 4) /**< \brief (HSMCI_DTOR) DTOCYC */
#define HSMCI_DTOR_DTOMUL_16 (0x1u << 4) /**< \brief (HSMCI_DTOR) DTOCYC x 16 */
#define HSMCI_DTOR_DTOMUL_128 (0x2u << 4) /**< \brief (HSMCI_DTOR) DTOCYC x 128 */
#define HSMCI_DTOR_DTOMUL_256 (0x3u << 4) /**< \brief (HSMCI_DTOR) DTOCYC x 256 */
#define HSMCI_DTOR_DTOMUL_1024 (0x4u << 4) /**< \brief (HSMCI_DTOR) DTOCYC x 1024 */
#define HSMCI_DTOR_DTOMUL_4096 (0x5u << 4) /**< \brief (HSMCI_DTOR) DTOCYC x 4096 */
#define HSMCI_DTOR_DTOMUL_65536 (0x6u << 4) /**< \brief (HSMCI_DTOR) DTOCYC x 65536 */
#define HSMCI_DTOR_DTOMUL_1048576 (0x7u << 4) /**< \brief (HSMCI_DTOR) DTOCYC x 1048576 */
/* -------- HSMCI_SDCR : (HSMCI Offset: 0x0C) SD/SDIO Card Register -------- */
#define HSMCI_SDCR_SDCSEL_Pos 0
#define HSMCI_SDCR_SDCSEL_Msk (0x3u << HSMCI_SDCR_SDCSEL_Pos) /**< \brief (HSMCI_SDCR) SDCard/SDIO Slot */
#define HSMCI_SDCR_SDCSEL_SLOTA (0x0u << 0) /**< \brief (HSMCI_SDCR) Slot A is selected. */
#define HSMCI_SDCR_SDCSEL_SLOTB (0x1u << 0) /**< \brief (HSMCI_SDCR) SDCARD/SDIO Slot B selected */
#define HSMCI_SDCR_SDCSEL_SLOTC (0x2u << 0) /**< \brief (HSMCI_SDCR) - */
#define HSMCI_SDCR_SDCSEL_SLOTD (0x3u << 0) /**< \brief (HSMCI_SDCR) - */
#define HSMCI_SDCR_SDCBUS_Pos 6
#define HSMCI_SDCR_SDCBUS_Msk (0x3u << HSMCI_SDCR_SDCBUS_Pos) /**< \brief (HSMCI_SDCR) SDCard/SDIO Bus Width */
#define HSMCI_SDCR_SDCBUS_1 (0x0u << 6) /**< \brief (HSMCI_SDCR) 1 bit */
#define HSMCI_SDCR_SDCBUS_4 (0x2u << 6) /**< \brief (HSMCI_SDCR) 4 bit */
#define HSMCI_SDCR_SDCBUS_8 (0x3u << 6) /**< \brief (HSMCI_SDCR) 8 bit */
/* -------- HSMCI_ARGR : (HSMCI Offset: 0x10) Argument Register -------- */
#define HSMCI_ARGR_ARG_Pos 0
#define HSMCI_ARGR_ARG_Msk (0xffffffffu << HSMCI_ARGR_ARG_Pos) /**< \brief (HSMCI_ARGR) Command Argument */
#define HSMCI_ARGR_ARG(value) ((HSMCI_ARGR_ARG_Msk & ((value) << HSMCI_ARGR_ARG_Pos)))
/* -------- HSMCI_CMDR : (HSMCI Offset: 0x14) Command Register -------- */
#define HSMCI_CMDR_CMDNB_Pos 0
#define HSMCI_CMDR_CMDNB_Msk (0x3fu << HSMCI_CMDR_CMDNB_Pos) /**< \brief (HSMCI_CMDR) Command Number */
#define HSMCI_CMDR_CMDNB(value) ((HSMCI_CMDR_CMDNB_Msk & ((value) << HSMCI_CMDR_CMDNB_Pos)))
#define HSMCI_CMDR_RSPTYP_Pos 6
#define HSMCI_CMDR_RSPTYP_Msk (0x3u << HSMCI_CMDR_RSPTYP_Pos) /**< \brief (HSMCI_CMDR) Response Type */
#define HSMCI_CMDR_RSPTYP_NORESP (0x0u << 6) /**< \brief (HSMCI_CMDR) No response. */
#define HSMCI_CMDR_RSPTYP_48_BIT (0x1u << 6) /**< \brief (HSMCI_CMDR) 48-bit response. */
#define HSMCI_CMDR_RSPTYP_136_BIT (0x2u << 6) /**< \brief (HSMCI_CMDR) 136-bit response. */
#define HSMCI_CMDR_RSPTYP_R1B (0x3u << 6) /**< \brief (HSMCI_CMDR) R1b response type */
#define HSMCI_CMDR_SPCMD_Pos 8
#define HSMCI_CMDR_SPCMD_Msk (0x7u << HSMCI_CMDR_SPCMD_Pos) /**< \brief (HSMCI_CMDR) Special Command */
#define HSMCI_CMDR_SPCMD_STD (0x0u << 8) /**< \brief (HSMCI_CMDR) Not a special CMD. */
#define HSMCI_CMDR_SPCMD_INIT (0x1u << 8) /**< \brief (HSMCI_CMDR) Initialization CMD: 74 clock cycles for initialization sequence. */
#define HSMCI_CMDR_SPCMD_SYNC (0x2u << 8) /**< \brief (HSMCI_CMDR) Synchronized CMD: Wait for the end of the current data block transfer before sending the pending command. */
#define HSMCI_CMDR_SPCMD_CE_ATA (0x3u << 8) /**< \brief (HSMCI_CMDR) CE-ATA Completion Signal disable Command. The host cancels the ability for the device to return a command completion signal on the command line. */
#define HSMCI_CMDR_SPCMD_IT_CMD (0x4u << 8) /**< \brief (HSMCI_CMDR) Interrupt command: Corresponds to the Interrupt Mode (CMD40). */
#define HSMCI_CMDR_SPCMD_IT_RESP (0x5u << 8) /**< \brief (HSMCI_CMDR) Interrupt response: Corresponds to the Interrupt Mode (CMD40). */
#define HSMCI_CMDR_SPCMD_BOR (0x6u << 8) /**< \brief (HSMCI_CMDR) Boot Operation Request. Start a boot operation mode, the host processor can read boot data from the MMC device directly. */
#define HSMCI_CMDR_SPCMD_EBO (0x7u << 8) /**< \brief (HSMCI_CMDR) End Boot Operation. This command allows the host processor to terminate the boot operation mode. */
#define HSMCI_CMDR_OPDCMD (0x1u << 11) /**< \brief (HSMCI_CMDR) Open Drain Command */
#define HSMCI_CMDR_OPDCMD_PUSHPULL (0x0u << 11) /**< \brief (HSMCI_CMDR) Push pull command. */
#define HSMCI_CMDR_OPDCMD_OPENDRAIN (0x1u << 11) /**< \brief (HSMCI_CMDR) Open drain command. */
#define HSMCI_CMDR_MAXLAT (0x1u << 12) /**< \brief (HSMCI_CMDR) Max Latency for Command to Response */
#define HSMCI_CMDR_MAXLAT_5 (0x0u << 12) /**< \brief (HSMCI_CMDR) 5-cycle max latency. */
#define HSMCI_CMDR_MAXLAT_64 (0x1u << 12) /**< \brief (HSMCI_CMDR) 64-cycle max latency. */
#define HSMCI_CMDR_TRCMD_Pos 16
#define HSMCI_CMDR_TRCMD_Msk (0x3u << HSMCI_CMDR_TRCMD_Pos) /**< \brief (HSMCI_CMDR) Transfer Command */
#define HSMCI_CMDR_TRCMD_NO_DATA (0x0u << 16) /**< \brief (HSMCI_CMDR) No data transfer */
#define HSMCI_CMDR_TRCMD_START_DATA (0x1u << 16) /**< \brief (HSMCI_CMDR) Start data transfer */
#define HSMCI_CMDR_TRCMD_STOP_DATA (0x2u << 16) /**< \brief (HSMCI_CMDR) Stop data transfer */
#define HSMCI_CMDR_TRDIR (0x1u << 18) /**< \brief (HSMCI_CMDR) Transfer Direction */
#define HSMCI_CMDR_TRDIR_WRITE (0x0u << 18) /**< \brief (HSMCI_CMDR) Write. */
#define HSMCI_CMDR_TRDIR_READ (0x1u << 18) /**< \brief (HSMCI_CMDR) Read. */
#define HSMCI_CMDR_TRTYP_Pos 19
#define HSMCI_CMDR_TRTYP_Msk (0x7u << HSMCI_CMDR_TRTYP_Pos) /**< \brief (HSMCI_CMDR) Transfer Type */
#define HSMCI_CMDR_TRTYP_SINGLE (0x0u << 19) /**< \brief (HSMCI_CMDR) MMC/SDCard Single Block */
#define HSMCI_CMDR_TRTYP_MULTIPLE (0x1u << 19) /**< \brief (HSMCI_CMDR) MMC/SDCard Multiple Block */
#define HSMCI_CMDR_TRTYP_STREAM (0x2u << 19) /**< \brief (HSMCI_CMDR) MMC Stream */
#define HSMCI_CMDR_TRTYP_BYTE (0x4u << 19) /**< \brief (HSMCI_CMDR) SDIO Byte */
#define HSMCI_CMDR_TRTYP_BLOCK (0x5u << 19) /**< \brief (HSMCI_CMDR) SDIO Block */
#define HSMCI_CMDR_IOSPCMD_Pos 24
#define HSMCI_CMDR_IOSPCMD_Msk (0x3u << HSMCI_CMDR_IOSPCMD_Pos) /**< \brief (HSMCI_CMDR) SDIO Special Command */
#define HSMCI_CMDR_IOSPCMD_STD (0x0u << 24) /**< \brief (HSMCI_CMDR) Not an SDIO Special Command */
#define HSMCI_CMDR_IOSPCMD_SUSPEND (0x1u << 24) /**< \brief (HSMCI_CMDR) SDIO Suspend Command */
#define HSMCI_CMDR_IOSPCMD_RESUME (0x2u << 24) /**< \brief (HSMCI_CMDR) SDIO Resume Command */
#define HSMCI_CMDR_ATACS (0x1u << 26) /**< \brief (HSMCI_CMDR) ATA with Command Completion Signal */
#define HSMCI_CMDR_ATACS_NORMAL (0x0u << 26) /**< \brief (HSMCI_CMDR) Normal operation mode. */
#define HSMCI_CMDR_ATACS_COMPLETION (0x1u << 26) /**< \brief (HSMCI_CMDR) This bit indicates that a completion signal is expected within a programmed amount of time (HSMCI_CSTOR). */
#define HSMCI_CMDR_BOOT_ACK (0x1u << 27) /**< \brief (HSMCI_CMDR) Boot Operation Acknowledge. */
/* -------- HSMCI_BLKR : (HSMCI Offset: 0x18) Block Register -------- */
#define HSMCI_BLKR_BCNT_Pos 0
#define HSMCI_BLKR_BCNT_Msk (0xffffu << HSMCI_BLKR_BCNT_Pos) /**< \brief (HSMCI_BLKR) MMC/SDIO Block Count - SDIO Byte Count */
#define HSMCI_BLKR_BCNT_MULTIPLE (0x0u << 0) /**< \brief (HSMCI_BLKR) MMC/SDCARD Multiple BlockFrom 1 to 65635: Value 0 corresponds to an infinite block transfer. */
#define HSMCI_BLKR_BCNT_BYTE (0x4u << 0) /**< \brief (HSMCI_BLKR) SDIO ByteFrom 1 to 512 bytes: Value 0 corresponds to a 512-byte transfer.Values from 0x200 to 0xFFFF are forbidden. */
#define HSMCI_BLKR_BCNT_BLOCK (0x5u << 0) /**< \brief (HSMCI_BLKR) SDIO BlockFrom 1 to 511 blocks: Value 0 corresponds to an infinite block transfer.Values from 0x200 to 0xFFFF are forbidden. */
#define HSMCI_BLKR_BLKLEN_Pos 16
#define HSMCI_BLKR_BLKLEN_Msk (0xffffu << HSMCI_BLKR_BLKLEN_Pos) /**< \brief (HSMCI_BLKR) Data Block Length */
#define HSMCI_BLKR_BLKLEN(value) ((HSMCI_BLKR_BLKLEN_Msk & ((value) << HSMCI_BLKR_BLKLEN_Pos)))
/* -------- HSMCI_CSTOR : (HSMCI Offset: 0x1C) Completion Signal Timeout Register -------- */
#define HSMCI_CSTOR_CSTOCYC_Pos 0
#define HSMCI_CSTOR_CSTOCYC_Msk (0xfu << HSMCI_CSTOR_CSTOCYC_Pos) /**< \brief (HSMCI_CSTOR) Completion Signal Timeout Cycle Number */
#define HSMCI_CSTOR_CSTOCYC(value) ((HSMCI_CSTOR_CSTOCYC_Msk & ((value) << HSMCI_CSTOR_CSTOCYC_Pos)))
#define HSMCI_CSTOR_CSTOMUL_Pos 4
#define HSMCI_CSTOR_CSTOMUL_Msk (0x7u << HSMCI_CSTOR_CSTOMUL_Pos) /**< \brief (HSMCI_CSTOR) Completion Signal Timeout Multiplier */
#define HSMCI_CSTOR_CSTOMUL_1 (0x0u << 4) /**< \brief (HSMCI_CSTOR) CSTOCYC x 1 */
#define HSMCI_CSTOR_CSTOMUL_16 (0x1u << 4) /**< \brief (HSMCI_CSTOR) CSTOCYC x 16 */
#define HSMCI_CSTOR_CSTOMUL_128 (0x2u << 4) /**< \brief (HSMCI_CSTOR) CSTOCYC x 128 */
#define HSMCI_CSTOR_CSTOMUL_256 (0x3u << 4) /**< \brief (HSMCI_CSTOR) CSTOCYC x 256 */
#define HSMCI_CSTOR_CSTOMUL_1024 (0x4u << 4) /**< \brief (HSMCI_CSTOR) CSTOCYC x 1024 */
#define HSMCI_CSTOR_CSTOMUL_4096 (0x5u << 4) /**< \brief (HSMCI_CSTOR) CSTOCYC x 4096 */
#define HSMCI_CSTOR_CSTOMUL_65536 (0x6u << 4) /**< \brief (HSMCI_CSTOR) CSTOCYC x 65536 */
#define HSMCI_CSTOR_CSTOMUL_1048576 (0x7u << 4) /**< \brief (HSMCI_CSTOR) CSTOCYC x 1048576 */
/* -------- HSMCI_RSPR[4] : (HSMCI Offset: 0x20) Response Register -------- */
#define HSMCI_RSPR_RSP_Pos 0
#define HSMCI_RSPR_RSP_Msk (0xffffffffu << HSMCI_RSPR_RSP_Pos) /**< \brief (HSMCI_RSPR[4]) Response */
/* -------- HSMCI_RDR : (HSMCI Offset: 0x30) Receive Data Register -------- */
#define HSMCI_RDR_DATA_Pos 0
#define HSMCI_RDR_DATA_Msk (0xffffffffu << HSMCI_RDR_DATA_Pos) /**< \brief (HSMCI_RDR) Data to Read */
/* -------- HSMCI_TDR : (HSMCI Offset: 0x34) Transmit Data Register -------- */
#define HSMCI_TDR_DATA_Pos 0
#define HSMCI_TDR_DATA_Msk (0xffffffffu << HSMCI_TDR_DATA_Pos) /**< \brief (HSMCI_TDR) Data to Write */
#define HSMCI_TDR_DATA(value) ((HSMCI_TDR_DATA_Msk & ((value) << HSMCI_TDR_DATA_Pos)))
/* -------- HSMCI_SR : (HSMCI Offset: 0x40) Status Register -------- */
#define HSMCI_SR_CMDRDY (0x1u << 0) /**< \brief (HSMCI_SR) Command Ready */
#define HSMCI_SR_RXRDY (0x1u << 1) /**< \brief (HSMCI_SR) Receiver Ready */
#define HSMCI_SR_TXRDY (0x1u << 2) /**< \brief (HSMCI_SR) Transmit Ready */
#define HSMCI_SR_BLKE (0x1u << 3) /**< \brief (HSMCI_SR) Data Block Ended */
#define HSMCI_SR_DTIP (0x1u << 4) /**< \brief (HSMCI_SR) Data Transfer in Progress */
#define HSMCI_SR_NOTBUSY (0x1u << 5) /**< \brief (HSMCI_SR) HSMCI Not Busy */
#define HSMCI_SR_SDIOIRQforSlotA (0x1u << 8) /**< \brief (HSMCI_SR) */
#define HSMCI_SR_SDIOIRQforSlotB (0x1u << 9) /**< \brief (HSMCI_SR) */
#define HSMCI_SR_SDIOWAIT (0x1u << 12) /**< \brief (HSMCI_SR) SDIO Read Wait Operation Status */
#define HSMCI_SR_CSRCV (0x1u << 13) /**< \brief (HSMCI_SR) CE-ATA Completion Signal Received */
#define HSMCI_SR_RINDE (0x1u << 16) /**< \brief (HSMCI_SR) Response Index Error */
#define HSMCI_SR_RDIRE (0x1u << 17) /**< \brief (HSMCI_SR) Response Direction Error */
#define HSMCI_SR_RCRCE (0x1u << 18) /**< \brief (HSMCI_SR) Response CRC Error */
#define HSMCI_SR_RENDE (0x1u << 19) /**< \brief (HSMCI_SR) Response End Bit Error */
#define HSMCI_SR_RTOE (0x1u << 20) /**< \brief (HSMCI_SR) Response Time-out Error */
#define HSMCI_SR_DCRCE (0x1u << 21) /**< \brief (HSMCI_SR) Data CRC Error */
#define HSMCI_SR_DTOE (0x1u << 22) /**< \brief (HSMCI_SR) Data Time-out Error */
#define HSMCI_SR_CSTOE (0x1u << 23) /**< \brief (HSMCI_SR) Completion Signal Time-out Error */
#define HSMCI_SR_BLKOVRE (0x1u << 24) /**< \brief (HSMCI_SR) DMA Block Overrun Error */
#define HSMCI_SR_DMADONE (0x1u << 25) /**< \brief (HSMCI_SR) DMA Transfer done */
#define HSMCI_SR_FIFOEMPTY (0x1u << 26) /**< \brief (HSMCI_SR) FIFO empty flag */
#define HSMCI_SR_XFRDONE (0x1u << 27) /**< \brief (HSMCI_SR) Transfer Done flag */
#define HSMCI_SR_ACKRCV (0x1u << 28) /**< \brief (HSMCI_SR) Boot Operation Acknowledge Received */
#define HSMCI_SR_ACKRCVE (0x1u << 29) /**< \brief (HSMCI_SR) Boot Operation Acknowledge Error */
#define HSMCI_SR_OVRE (0x1u << 30) /**< \brief (HSMCI_SR) Overrun */
#define HSMCI_SR_UNRE (0x1u << 31) /**< \brief (HSMCI_SR) Underrun */
/* -------- HSMCI_IER : (HSMCI Offset: 0x44) Interrupt Enable Register -------- */
#define HSMCI_IER_CMDRDY (0x1u << 0) /**< \brief (HSMCI_IER) Command Ready Interrupt Enable */
#define HSMCI_IER_RXRDY (0x1u << 1) /**< \brief (HSMCI_IER) Receiver Ready Interrupt Enable */
#define HSMCI_IER_TXRDY (0x1u << 2) /**< \brief (HSMCI_IER) Transmit Ready Interrupt Enable */
#define HSMCI_IER_BLKE (0x1u << 3) /**< \brief (HSMCI_IER) Data Block Ended Interrupt Enable */
#define HSMCI_IER_DTIP (0x1u << 4) /**< \brief (HSMCI_IER) Data Transfer in Progress Interrupt Enable */
#define HSMCI_IER_NOTBUSY (0x1u << 5) /**< \brief (HSMCI_IER) Data Not Busy Interrupt Enable */
#define HSMCI_IER_SDIOIRQforSlotA (0x1u << 8) /**< \brief (HSMCI_IER) */
#define HSMCI_IER_SDIOIRQforSlotB (0x1u << 9) /**< \brief (HSMCI_IER) */
#define HSMCI_IER_SDIOWAIT (0x1u << 12) /**< \brief (HSMCI_IER) SDIO Read Wait Operation Status Interrupt Enable */
#define HSMCI_IER_CSRCV (0x1u << 13) /**< \brief (HSMCI_IER) Completion Signal Received Interrupt Enable */
#define HSMCI_IER_RINDE (0x1u << 16) /**< \brief (HSMCI_IER) Response Index Error Interrupt Enable */
#define HSMCI_IER_RDIRE (0x1u << 17) /**< \brief (HSMCI_IER) Response Direction Error Interrupt Enable */
#define HSMCI_IER_RCRCE (0x1u << 18) /**< \brief (HSMCI_IER) Response CRC Error Interrupt Enable */
#define HSMCI_IER_RENDE (0x1u << 19) /**< \brief (HSMCI_IER) Response End Bit Error Interrupt Enable */
#define HSMCI_IER_RTOE (0x1u << 20) /**< \brief (HSMCI_IER) Response Time-out Error Interrupt Enable */
#define HSMCI_IER_DCRCE (0x1u << 21) /**< \brief (HSMCI_IER) Data CRC Error Interrupt Enable */
#define HSMCI_IER_DTOE (0x1u << 22) /**< \brief (HSMCI_IER) Data Time-out Error Interrupt Enable */
#define HSMCI_IER_CSTOE (0x1u << 23) /**< \brief (HSMCI_IER) Completion Signal Timeout Error Interrupt Enable */
#define HSMCI_IER_BLKOVRE (0x1u << 24) /**< \brief (HSMCI_IER) DMA Block Overrun Error Interrupt Enable */
#define HSMCI_IER_DMADONE (0x1u << 25) /**< \brief (HSMCI_IER) DMA Transfer completed Interrupt Enable */
#define HSMCI_IER_FIFOEMPTY (0x1u << 26) /**< \brief (HSMCI_IER) FIFO empty Interrupt enable */
#define HSMCI_IER_XFRDONE (0x1u << 27) /**< \brief (HSMCI_IER) Transfer Done Interrupt enable */
#define HSMCI_IER_ACKRCV (0x1u << 28) /**< \brief (HSMCI_IER) Boot Acknowledge Interrupt Enable */
#define HSMCI_IER_ACKRCVE (0x1u << 29) /**< \brief (HSMCI_IER) Boot Acknowledge Error Interrupt Enable */
#define HSMCI_IER_OVRE (0x1u << 30) /**< \brief (HSMCI_IER) Overrun Interrupt Enable */
#define HSMCI_IER_UNRE (0x1u << 31) /**< \brief (HSMCI_IER) Underrun Interrupt Enable */
/* -------- HSMCI_IDR : (HSMCI Offset: 0x48) Interrupt Disable Register -------- */
#define HSMCI_IDR_CMDRDY (0x1u << 0) /**< \brief (HSMCI_IDR) Command Ready Interrupt Disable */
#define HSMCI_IDR_RXRDY (0x1u << 1) /**< \brief (HSMCI_IDR) Receiver Ready Interrupt Disable */
#define HSMCI_IDR_TXRDY (0x1u << 2) /**< \brief (HSMCI_IDR) Transmit Ready Interrupt Disable */
#define HSMCI_IDR_BLKE (0x1u << 3) /**< \brief (HSMCI_IDR) Data Block Ended Interrupt Disable */
#define HSMCI_IDR_DTIP (0x1u << 4) /**< \brief (HSMCI_IDR) Data Transfer in Progress Interrupt Disable */
#define HSMCI_IDR_NOTBUSY (0x1u << 5) /**< \brief (HSMCI_IDR) Data Not Busy Interrupt Disable */
#define HSMCI_IDR_SDIOIRQforSlotA (0x1u << 8) /**< \brief (HSMCI_IDR) */
#define HSMCI_IDR_SDIOIRQforSlotB (0x1u << 9) /**< \brief (HSMCI_IDR) */
#define HSMCI_IDR_SDIOWAIT (0x1u << 12) /**< \brief (HSMCI_IDR) SDIO Read Wait Operation Status Interrupt Disable */
#define HSMCI_IDR_CSRCV (0x1u << 13) /**< \brief (HSMCI_IDR) Completion Signal received interrupt Disable */
#define HSMCI_IDR_RINDE (0x1u << 16) /**< \brief (HSMCI_IDR) Response Index Error Interrupt Disable */
#define HSMCI_IDR_RDIRE (0x1u << 17) /**< \brief (HSMCI_IDR) Response Direction Error Interrupt Disable */
#define HSMCI_IDR_RCRCE (0x1u << 18) /**< \brief (HSMCI_IDR) Response CRC Error Interrupt Disable */
#define HSMCI_IDR_RENDE (0x1u << 19) /**< \brief (HSMCI_IDR) Response End Bit Error Interrupt Disable */
#define HSMCI_IDR_RTOE (0x1u << 20) /**< \brief (HSMCI_IDR) Response Time-out Error Interrupt Disable */
#define HSMCI_IDR_DCRCE (0x1u << 21) /**< \brief (HSMCI_IDR) Data CRC Error Interrupt Disable */
#define HSMCI_IDR_DTOE (0x1u << 22) /**< \brief (HSMCI_IDR) Data Time-out Error Interrupt Disable */
#define HSMCI_IDR_CSTOE (0x1u << 23) /**< \brief (HSMCI_IDR) Completion Signal Time out Error Interrupt Disable */
#define HSMCI_IDR_BLKOVRE (0x1u << 24) /**< \brief (HSMCI_IDR) DMA Block Overrun Error Interrupt Disable */
#define HSMCI_IDR_DMADONE (0x1u << 25) /**< \brief (HSMCI_IDR) DMA Transfer completed Interrupt Disable */
#define HSMCI_IDR_FIFOEMPTY (0x1u << 26) /**< \brief (HSMCI_IDR) FIFO empty Interrupt Disable */
#define HSMCI_IDR_XFRDONE (0x1u << 27) /**< \brief (HSMCI_IDR) Transfer Done Interrupt Disable */
#define HSMCI_IDR_ACKRCV (0x1u << 28) /**< \brief (HSMCI_IDR) Boot Acknowledge Interrupt Disable */
#define HSMCI_IDR_ACKRCVE (0x1u << 29) /**< \brief (HSMCI_IDR) Boot Acknowledge Error Interrupt Disable */
#define HSMCI_IDR_OVRE (0x1u << 30) /**< \brief (HSMCI_IDR) Overrun Interrupt Disable */
#define HSMCI_IDR_UNRE (0x1u << 31) /**< \brief (HSMCI_IDR) Underrun Interrupt Disable */
/* -------- HSMCI_IMR : (HSMCI Offset: 0x4C) Interrupt Mask Register -------- */
#define HSMCI_IMR_CMDRDY (0x1u << 0) /**< \brief (HSMCI_IMR) Command Ready Interrupt Mask */
#define HSMCI_IMR_RXRDY (0x1u << 1) /**< \brief (HSMCI_IMR) Receiver Ready Interrupt Mask */
#define HSMCI_IMR_TXRDY (0x1u << 2) /**< \brief (HSMCI_IMR) Transmit Ready Interrupt Mask */
#define HSMCI_IMR_BLKE (0x1u << 3) /**< \brief (HSMCI_IMR) Data Block Ended Interrupt Mask */
#define HSMCI_IMR_DTIP (0x1u << 4) /**< \brief (HSMCI_IMR) Data Transfer in Progress Interrupt Mask */
#define HSMCI_IMR_NOTBUSY (0x1u << 5) /**< \brief (HSMCI_IMR) Data Not Busy Interrupt Mask */
#define HSMCI_IMR_SDIOIRQforSlotA (0x1u << 8) /**< \brief (HSMCI_IMR) */
#define HSMCI_IMR_SDIOIRQforSlotB (0x1u << 9) /**< \brief (HSMCI_IMR) */
#define HSMCI_IMR_SDIOWAIT (0x1u << 12) /**< \brief (HSMCI_IMR) SDIO Read Wait Operation Status Interrupt Mask */
#define HSMCI_IMR_CSRCV (0x1u << 13) /**< \brief (HSMCI_IMR) Completion Signal Received Interrupt Mask */
#define HSMCI_IMR_RINDE (0x1u << 16) /**< \brief (HSMCI_IMR) Response Index Error Interrupt Mask */
#define HSMCI_IMR_RDIRE (0x1u << 17) /**< \brief (HSMCI_IMR) Response Direction Error Interrupt Mask */
#define HSMCI_IMR_RCRCE (0x1u << 18) /**< \brief (HSMCI_IMR) Response CRC Error Interrupt Mask */
#define HSMCI_IMR_RENDE (0x1u << 19) /**< \brief (HSMCI_IMR) Response End Bit Error Interrupt Mask */
#define HSMCI_IMR_RTOE (0x1u << 20) /**< \brief (HSMCI_IMR) Response Time-out Error Interrupt Mask */
#define HSMCI_IMR_DCRCE (0x1u << 21) /**< \brief (HSMCI_IMR) Data CRC Error Interrupt Mask */
#define HSMCI_IMR_DTOE (0x1u << 22) /**< \brief (HSMCI_IMR) Data Time-out Error Interrupt Mask */
#define HSMCI_IMR_CSTOE (0x1u << 23) /**< \brief (HSMCI_IMR) Completion Signal Time-out Error Interrupt Mask */
#define HSMCI_IMR_BLKOVRE (0x1u << 24) /**< \brief (HSMCI_IMR) DMA Block Overrun Error Interrupt Mask */
#define HSMCI_IMR_DMADONE (0x1u << 25) /**< \brief (HSMCI_IMR) DMA Transfer Completed Interrupt Mask */
#define HSMCI_IMR_FIFOEMPTY (0x1u << 26) /**< \brief (HSMCI_IMR) FIFO Empty Interrupt Mask */
#define HSMCI_IMR_XFRDONE (0x1u << 27) /**< \brief (HSMCI_IMR) Transfer Done Interrupt Mask */
#define HSMCI_IMR_ACKRCV (0x1u << 28) /**< \brief (HSMCI_IMR) Boot Operation Acknowledge Received Interrupt Mask */
#define HSMCI_IMR_ACKRCVE (0x1u << 29) /**< \brief (HSMCI_IMR) Boot Operation Acknowledge Error Interrupt Mask */
#define HSMCI_IMR_OVRE (0x1u << 30) /**< \brief (HSMCI_IMR) Overrun Interrupt Mask */
#define HSMCI_IMR_UNRE (0x1u << 31) /**< \brief (HSMCI_IMR) Underrun Interrupt Mask */
/* -------- HSMCI_DMA : (HSMCI Offset: 0x50) DMA Configuration Register -------- */
#define HSMCI_DMA_OFFSET_Pos 0
#define HSMCI_DMA_OFFSET_Msk (0x3u << HSMCI_DMA_OFFSET_Pos) /**< \brief (HSMCI_DMA) DMA Write Buffer Offset */
#define HSMCI_DMA_OFFSET(value) ((HSMCI_DMA_OFFSET_Msk & ((value) << HSMCI_DMA_OFFSET_Pos)))
#define HSMCI_DMA_CHKSIZE (0x1u << 4) /**< \brief (HSMCI_DMA) DMA Channel Read and Write Chunk Size */
#define HSMCI_DMA_CHKSIZE_1 (0x0u << 4) /**< \brief (HSMCI_DMA) 1 data available */
#define HSMCI_DMA_CHKSIZE_4 (0x1u << 4) /**< \brief (HSMCI_DMA) 4 data available */
#define HSMCI_DMA_DMAEN (0x1u << 8) /**< \brief (HSMCI_DMA) DMA Hardware Handshaking Enable */
#define HSMCI_DMA_ROPT (0x1u << 12) /**< \brief (HSMCI_DMA) Read Optimization with padding */
/* -------- HSMCI_CFG : (HSMCI Offset: 0x54) Configuration Register -------- */
#define HSMCI_CFG_FIFOMODE (0x1u << 0) /**< \brief (HSMCI_CFG) HSMCI Internal FIFO control mode */
#define HSMCI_CFG_FERRCTRL (0x1u << 4) /**< \brief (HSMCI_CFG) Flow Error flag reset control mode */
#define HSMCI_CFG_HSMODE (0x1u << 8) /**< \brief (HSMCI_CFG) High Speed Mode */
#define HSMCI_CFG_LSYNC (0x1u << 12) /**< \brief (HSMCI_CFG) Synchronize on the last block */
/* -------- HSMCI_WPMR : (HSMCI Offset: 0xE4) Write Protection Mode Register -------- */
#define HSMCI_WPMR_WP_EN (0x1u << 0) /**< \brief (HSMCI_WPMR) Write Protection Enable */
#define HSMCI_WPMR_WP_KEY_Pos 8
#define HSMCI_WPMR_WP_KEY_Msk (0xffffffu << HSMCI_WPMR_WP_KEY_Pos) /**< \brief (HSMCI_WPMR) Write Protection Key password */
#define HSMCI_WPMR_WP_KEY(value) ((HSMCI_WPMR_WP_KEY_Msk & ((value) << HSMCI_WPMR_WP_KEY_Pos)))
/* -------- HSMCI_WPSR : (HSMCI Offset: 0xE8) Write Protection Status Register -------- */
#define HSMCI_WPSR_WP_VS_Pos 0
#define HSMCI_WPSR_WP_VS_Msk (0xfu << HSMCI_WPSR_WP_VS_Pos) /**< \brief (HSMCI_WPSR) Write Protection Violation Status */
#define HSMCI_WPSR_WP_VS_NONE (0x0u << 0) /**< \brief (HSMCI_WPSR) No Write Protection Violation occurred since the last read of this register (WP_SR) */
#define HSMCI_WPSR_WP_VS_WRITE (0x1u << 0) /**< \brief (HSMCI_WPSR) Write Protection detected unauthorized attempt to write a control register had occurred (since the last read.) */
#define HSMCI_WPSR_WP_VS_RESET (0x2u << 0) /**< \brief (HSMCI_WPSR) Software reset had been performed while Write Protection was enabled (since the last read). */
#define HSMCI_WPSR_WP_VS_BOTH (0x3u << 0) /**< \brief (HSMCI_WPSR) Both Write Protection violation and software reset with Write Protection enabled have occurred since the last read. */
#define HSMCI_WPSR_WP_VSRC_Pos 8
#define HSMCI_WPSR_WP_VSRC_Msk (0xffffu << HSMCI_WPSR_WP_VSRC_Pos) /**< \brief (HSMCI_WPSR) Write Protection Violation SouRCe */
/* -------- HSMCI_FIFO[256] : (HSMCI Offset: 0x200) FIFO Memory Aperture0 -------- */
#define HSMCI_FIFO_DATA_Pos 0
#define HSMCI_FIFO_DATA_Msk (0xffffffffu << HSMCI_FIFO_DATA_Pos) /**< \brief (HSMCI_FIFO[256]) Data to Read or Data to Write */
#define HSMCI_FIFO_DATA(value) ((HSMCI_FIFO_DATA_Msk & ((value) << HSMCI_FIFO_DATA_Pos)))
/*@}*/
#endif /* _SAM3XA_HSMCI_COMPONENT_ */

View File

@@ -0,0 +1,285 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2012, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _SAM3XA_MATRIX_COMPONENT_
#define _SAM3XA_MATRIX_COMPONENT_
/* ============================================================================= */
/** SOFTWARE API DEFINITION FOR AHB Bus Matrix */
/* ============================================================================= */
/** \addtogroup SAM3XA_MATRIX AHB Bus Matrix */
/*@{*/
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
/** \brief Matrix hardware registers */
typedef struct {
RwReg MATRIX_MCFG[6]; /**< \brief (Matrix Offset: 0x0000) Master Configuration Register */
RoReg Reserved1[10];
RwReg MATRIX_SCFG[9]; /**< \brief (Matrix Offset: 0x0040) Slave Configuration Register */
RoReg Reserved2[7];
RwReg MATRIX_PRAS0; /**< \brief (Matrix Offset: 0x0080) Priority Register A for Slave 0 */
RoReg Reserved3[1];
RwReg MATRIX_PRAS1; /**< \brief (Matrix Offset: 0x0088) Priority Register A for Slave 1 */
RoReg Reserved4[1];
RwReg MATRIX_PRAS2; /**< \brief (Matrix Offset: 0x0090) Priority Register A for Slave 2 */
RoReg Reserved5[1];
RwReg MATRIX_PRAS3; /**< \brief (Matrix Offset: 0x0098) Priority Register A for Slave 3 */
RoReg Reserved6[1];
RwReg MATRIX_PRAS4; /**< \brief (Matrix Offset: 0x00A0) Priority Register A for Slave 4 */
RoReg Reserved7[1];
RwReg MATRIX_PRAS5; /**< \brief (Matrix Offset: 0x00A8) Priority Register A for Slave 5 */
RoReg Reserved8[1];
RwReg MATRIX_PRAS6; /**< \brief (Matrix Offset: 0x00B0) Priority Register A for Slave 6 */
RoReg Reserved9[1];
RwReg MATRIX_PRAS7; /**< \brief (Matrix Offset: 0x00B8) Priority Register A for Slave 7 */
RoReg Reserved10[1];
RwReg MATRIX_PRAS8; /**< \brief (Matrix Offset: 0x00C0) Priority Register A for Slave 8 */
RoReg Reserved11[1];
RoReg Reserved12[14];
RwReg MATRIX_MRCR; /**< \brief (Matrix Offset: 0x0100) Master Remap Control Register */
RoReg Reserved13[4];
RwReg CCFG_SYSIO; /**< \brief (Matrix Offset: 0x0114) System I/O Configuration register */
RoReg Reserved14[51];
RwReg MATRIX_WPMR; /**< \brief (Matrix Offset: 0x1E4) Write Protect Mode Register */
RoReg MATRIX_WPSR; /**< \brief (Matrix Offset: 0x1E8) Write Protect Status Register */
} Matrix;
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
/* -------- MATRIX_MCFG[6] : (MATRIX Offset: 0x0000) Master Configuration Register -------- */
#define MATRIX_MCFG_ULBT_Pos 0
#define MATRIX_MCFG_ULBT_Msk (0x7u << MATRIX_MCFG_ULBT_Pos) /**< \brief (MATRIX_MCFG[6]) Undefined Length Burst Type */
#define MATRIX_MCFG_ULBT(value) ((MATRIX_MCFG_ULBT_Msk & ((value) << MATRIX_MCFG_ULBT_Pos)))
/* -------- MATRIX_SCFG[9] : (MATRIX Offset: 0x0040) Slave Configuration Register -------- */
#define MATRIX_SCFG_SLOT_CYCLE_Pos 0
#define MATRIX_SCFG_SLOT_CYCLE_Msk (0xffu << MATRIX_SCFG_SLOT_CYCLE_Pos) /**< \brief (MATRIX_SCFG[9]) Maximum Number of Allowed Cycles for a Burst */
#define MATRIX_SCFG_SLOT_CYCLE(value) ((MATRIX_SCFG_SLOT_CYCLE_Msk & ((value) << MATRIX_SCFG_SLOT_CYCLE_Pos)))
#define MATRIX_SCFG_DEFMSTR_TYPE_Pos 16
#define MATRIX_SCFG_DEFMSTR_TYPE_Msk (0x3u << MATRIX_SCFG_DEFMSTR_TYPE_Pos) /**< \brief (MATRIX_SCFG[9]) Default Master Type */
#define MATRIX_SCFG_DEFMSTR_TYPE(value) ((MATRIX_SCFG_DEFMSTR_TYPE_Msk & ((value) << MATRIX_SCFG_DEFMSTR_TYPE_Pos)))
#define MATRIX_SCFG_FIXED_DEFMSTR_Pos 18
#define MATRIX_SCFG_FIXED_DEFMSTR_Msk (0x7u << MATRIX_SCFG_FIXED_DEFMSTR_Pos) /**< \brief (MATRIX_SCFG[9]) Fixed Default Master */
#define MATRIX_SCFG_FIXED_DEFMSTR(value) ((MATRIX_SCFG_FIXED_DEFMSTR_Msk & ((value) << MATRIX_SCFG_FIXED_DEFMSTR_Pos)))
#define MATRIX_SCFG_ARBT_Pos 24
#define MATRIX_SCFG_ARBT_Msk (0x3u << MATRIX_SCFG_ARBT_Pos) /**< \brief (MATRIX_SCFG[9]) Arbitration Type */
#define MATRIX_SCFG_ARBT(value) ((MATRIX_SCFG_ARBT_Msk & ((value) << MATRIX_SCFG_ARBT_Pos)))
/* -------- MATRIX_PRAS0 : (MATRIX Offset: 0x0080) Priority Register A for Slave 0 -------- */
#define MATRIX_PRAS0_M0PR_Pos 0
#define MATRIX_PRAS0_M0PR_Msk (0x3u << MATRIX_PRAS0_M0PR_Pos) /**< \brief (MATRIX_PRAS0) Master 0 Priority */
#define MATRIX_PRAS0_M0PR(value) ((MATRIX_PRAS0_M0PR_Msk & ((value) << MATRIX_PRAS0_M0PR_Pos)))
#define MATRIX_PRAS0_M1PR_Pos 4
#define MATRIX_PRAS0_M1PR_Msk (0x3u << MATRIX_PRAS0_M1PR_Pos) /**< \brief (MATRIX_PRAS0) Master 1 Priority */
#define MATRIX_PRAS0_M1PR(value) ((MATRIX_PRAS0_M1PR_Msk & ((value) << MATRIX_PRAS0_M1PR_Pos)))
#define MATRIX_PRAS0_M2PR_Pos 8
#define MATRIX_PRAS0_M2PR_Msk (0x3u << MATRIX_PRAS0_M2PR_Pos) /**< \brief (MATRIX_PRAS0) Master 2 Priority */
#define MATRIX_PRAS0_M2PR(value) ((MATRIX_PRAS0_M2PR_Msk & ((value) << MATRIX_PRAS0_M2PR_Pos)))
#define MATRIX_PRAS0_M3PR_Pos 12
#define MATRIX_PRAS0_M3PR_Msk (0x3u << MATRIX_PRAS0_M3PR_Pos) /**< \brief (MATRIX_PRAS0) Master 3 Priority */
#define MATRIX_PRAS0_M3PR(value) ((MATRIX_PRAS0_M3PR_Msk & ((value) << MATRIX_PRAS0_M3PR_Pos)))
#define MATRIX_PRAS0_M4PR_Pos 16
#define MATRIX_PRAS0_M4PR_Msk (0x3u << MATRIX_PRAS0_M4PR_Pos) /**< \brief (MATRIX_PRAS0) Master 4 Priority */
#define MATRIX_PRAS0_M4PR(value) ((MATRIX_PRAS0_M4PR_Msk & ((value) << MATRIX_PRAS0_M4PR_Pos)))
#define MATRIX_PRAS0_M5PR_Pos 20
#define MATRIX_PRAS0_M5PR_Msk (0x3u << MATRIX_PRAS0_M5PR_Pos) /**< \brief (MATRIX_PRAS0) Master 5 Priority */
#define MATRIX_PRAS0_M5PR(value) ((MATRIX_PRAS0_M5PR_Msk & ((value) << MATRIX_PRAS0_M5PR_Pos)))
/* -------- MATRIX_PRAS1 : (MATRIX Offset: 0x0088) Priority Register A for Slave 1 -------- */
#define MATRIX_PRAS1_M0PR_Pos 0
#define MATRIX_PRAS1_M0PR_Msk (0x3u << MATRIX_PRAS1_M0PR_Pos) /**< \brief (MATRIX_PRAS1) Master 0 Priority */
#define MATRIX_PRAS1_M0PR(value) ((MATRIX_PRAS1_M0PR_Msk & ((value) << MATRIX_PRAS1_M0PR_Pos)))
#define MATRIX_PRAS1_M1PR_Pos 4
#define MATRIX_PRAS1_M1PR_Msk (0x3u << MATRIX_PRAS1_M1PR_Pos) /**< \brief (MATRIX_PRAS1) Master 1 Priority */
#define MATRIX_PRAS1_M1PR(value) ((MATRIX_PRAS1_M1PR_Msk & ((value) << MATRIX_PRAS1_M1PR_Pos)))
#define MATRIX_PRAS1_M2PR_Pos 8
#define MATRIX_PRAS1_M2PR_Msk (0x3u << MATRIX_PRAS1_M2PR_Pos) /**< \brief (MATRIX_PRAS1) Master 2 Priority */
#define MATRIX_PRAS1_M2PR(value) ((MATRIX_PRAS1_M2PR_Msk & ((value) << MATRIX_PRAS1_M2PR_Pos)))
#define MATRIX_PRAS1_M3PR_Pos 12
#define MATRIX_PRAS1_M3PR_Msk (0x3u << MATRIX_PRAS1_M3PR_Pos) /**< \brief (MATRIX_PRAS1) Master 3 Priority */
#define MATRIX_PRAS1_M3PR(value) ((MATRIX_PRAS1_M3PR_Msk & ((value) << MATRIX_PRAS1_M3PR_Pos)))
#define MATRIX_PRAS1_M4PR_Pos 16
#define MATRIX_PRAS1_M4PR_Msk (0x3u << MATRIX_PRAS1_M4PR_Pos) /**< \brief (MATRIX_PRAS1) Master 4 Priority */
#define MATRIX_PRAS1_M4PR(value) ((MATRIX_PRAS1_M4PR_Msk & ((value) << MATRIX_PRAS1_M4PR_Pos)))
#define MATRIX_PRAS1_M5PR_Pos 20
#define MATRIX_PRAS1_M5PR_Msk (0x3u << MATRIX_PRAS1_M5PR_Pos) /**< \brief (MATRIX_PRAS1) Master 5 Priority */
#define MATRIX_PRAS1_M5PR(value) ((MATRIX_PRAS1_M5PR_Msk & ((value) << MATRIX_PRAS1_M5PR_Pos)))
/* -------- MATRIX_PRAS2 : (MATRIX Offset: 0x0090) Priority Register A for Slave 2 -------- */
#define MATRIX_PRAS2_M0PR_Pos 0
#define MATRIX_PRAS2_M0PR_Msk (0x3u << MATRIX_PRAS2_M0PR_Pos) /**< \brief (MATRIX_PRAS2) Master 0 Priority */
#define MATRIX_PRAS2_M0PR(value) ((MATRIX_PRAS2_M0PR_Msk & ((value) << MATRIX_PRAS2_M0PR_Pos)))
#define MATRIX_PRAS2_M1PR_Pos 4
#define MATRIX_PRAS2_M1PR_Msk (0x3u << MATRIX_PRAS2_M1PR_Pos) /**< \brief (MATRIX_PRAS2) Master 1 Priority */
#define MATRIX_PRAS2_M1PR(value) ((MATRIX_PRAS2_M1PR_Msk & ((value) << MATRIX_PRAS2_M1PR_Pos)))
#define MATRIX_PRAS2_M2PR_Pos 8
#define MATRIX_PRAS2_M2PR_Msk (0x3u << MATRIX_PRAS2_M2PR_Pos) /**< \brief (MATRIX_PRAS2) Master 2 Priority */
#define MATRIX_PRAS2_M2PR(value) ((MATRIX_PRAS2_M2PR_Msk & ((value) << MATRIX_PRAS2_M2PR_Pos)))
#define MATRIX_PRAS2_M3PR_Pos 12
#define MATRIX_PRAS2_M3PR_Msk (0x3u << MATRIX_PRAS2_M3PR_Pos) /**< \brief (MATRIX_PRAS2) Master 3 Priority */
#define MATRIX_PRAS2_M3PR(value) ((MATRIX_PRAS2_M3PR_Msk & ((value) << MATRIX_PRAS2_M3PR_Pos)))
#define MATRIX_PRAS2_M4PR_Pos 16
#define MATRIX_PRAS2_M4PR_Msk (0x3u << MATRIX_PRAS2_M4PR_Pos) /**< \brief (MATRIX_PRAS2) Master 4 Priority */
#define MATRIX_PRAS2_M4PR(value) ((MATRIX_PRAS2_M4PR_Msk & ((value) << MATRIX_PRAS2_M4PR_Pos)))
#define MATRIX_PRAS2_M5PR_Pos 20
#define MATRIX_PRAS2_M5PR_Msk (0x3u << MATRIX_PRAS2_M5PR_Pos) /**< \brief (MATRIX_PRAS2) Master 5 Priority */
#define MATRIX_PRAS2_M5PR(value) ((MATRIX_PRAS2_M5PR_Msk & ((value) << MATRIX_PRAS2_M5PR_Pos)))
/* -------- MATRIX_PRAS3 : (MATRIX Offset: 0x0098) Priority Register A for Slave 3 -------- */
#define MATRIX_PRAS3_M0PR_Pos 0
#define MATRIX_PRAS3_M0PR_Msk (0x3u << MATRIX_PRAS3_M0PR_Pos) /**< \brief (MATRIX_PRAS3) Master 0 Priority */
#define MATRIX_PRAS3_M0PR(value) ((MATRIX_PRAS3_M0PR_Msk & ((value) << MATRIX_PRAS3_M0PR_Pos)))
#define MATRIX_PRAS3_M1PR_Pos 4
#define MATRIX_PRAS3_M1PR_Msk (0x3u << MATRIX_PRAS3_M1PR_Pos) /**< \brief (MATRIX_PRAS3) Master 1 Priority */
#define MATRIX_PRAS3_M1PR(value) ((MATRIX_PRAS3_M1PR_Msk & ((value) << MATRIX_PRAS3_M1PR_Pos)))
#define MATRIX_PRAS3_M2PR_Pos 8
#define MATRIX_PRAS3_M2PR_Msk (0x3u << MATRIX_PRAS3_M2PR_Pos) /**< \brief (MATRIX_PRAS3) Master 2 Priority */
#define MATRIX_PRAS3_M2PR(value) ((MATRIX_PRAS3_M2PR_Msk & ((value) << MATRIX_PRAS3_M2PR_Pos)))
#define MATRIX_PRAS3_M3PR_Pos 12
#define MATRIX_PRAS3_M3PR_Msk (0x3u << MATRIX_PRAS3_M3PR_Pos) /**< \brief (MATRIX_PRAS3) Master 3 Priority */
#define MATRIX_PRAS3_M3PR(value) ((MATRIX_PRAS3_M3PR_Msk & ((value) << MATRIX_PRAS3_M3PR_Pos)))
#define MATRIX_PRAS3_M4PR_Pos 16
#define MATRIX_PRAS3_M4PR_Msk (0x3u << MATRIX_PRAS3_M4PR_Pos) /**< \brief (MATRIX_PRAS3) Master 4 Priority */
#define MATRIX_PRAS3_M4PR(value) ((MATRIX_PRAS3_M4PR_Msk & ((value) << MATRIX_PRAS3_M4PR_Pos)))
#define MATRIX_PRAS3_M5PR_Pos 20
#define MATRIX_PRAS3_M5PR_Msk (0x3u << MATRIX_PRAS3_M5PR_Pos) /**< \brief (MATRIX_PRAS3) Master 5 Priority */
#define MATRIX_PRAS3_M5PR(value) ((MATRIX_PRAS3_M5PR_Msk & ((value) << MATRIX_PRAS3_M5PR_Pos)))
/* -------- MATRIX_PRAS4 : (MATRIX Offset: 0x00A0) Priority Register A for Slave 4 -------- */
#define MATRIX_PRAS4_M0PR_Pos 0
#define MATRIX_PRAS4_M0PR_Msk (0x3u << MATRIX_PRAS4_M0PR_Pos) /**< \brief (MATRIX_PRAS4) Master 0 Priority */
#define MATRIX_PRAS4_M0PR(value) ((MATRIX_PRAS4_M0PR_Msk & ((value) << MATRIX_PRAS4_M0PR_Pos)))
#define MATRIX_PRAS4_M1PR_Pos 4
#define MATRIX_PRAS4_M1PR_Msk (0x3u << MATRIX_PRAS4_M1PR_Pos) /**< \brief (MATRIX_PRAS4) Master 1 Priority */
#define MATRIX_PRAS4_M1PR(value) ((MATRIX_PRAS4_M1PR_Msk & ((value) << MATRIX_PRAS4_M1PR_Pos)))
#define MATRIX_PRAS4_M2PR_Pos 8
#define MATRIX_PRAS4_M2PR_Msk (0x3u << MATRIX_PRAS4_M2PR_Pos) /**< \brief (MATRIX_PRAS4) Master 2 Priority */
#define MATRIX_PRAS4_M2PR(value) ((MATRIX_PRAS4_M2PR_Msk & ((value) << MATRIX_PRAS4_M2PR_Pos)))
#define MATRIX_PRAS4_M3PR_Pos 12
#define MATRIX_PRAS4_M3PR_Msk (0x3u << MATRIX_PRAS4_M3PR_Pos) /**< \brief (MATRIX_PRAS4) Master 3 Priority */
#define MATRIX_PRAS4_M3PR(value) ((MATRIX_PRAS4_M3PR_Msk & ((value) << MATRIX_PRAS4_M3PR_Pos)))
#define MATRIX_PRAS4_M4PR_Pos 16
#define MATRIX_PRAS4_M4PR_Msk (0x3u << MATRIX_PRAS4_M4PR_Pos) /**< \brief (MATRIX_PRAS4) Master 4 Priority */
#define MATRIX_PRAS4_M4PR(value) ((MATRIX_PRAS4_M4PR_Msk & ((value) << MATRIX_PRAS4_M4PR_Pos)))
#define MATRIX_PRAS4_M5PR_Pos 20
#define MATRIX_PRAS4_M5PR_Msk (0x3u << MATRIX_PRAS4_M5PR_Pos) /**< \brief (MATRIX_PRAS4) Master 5 Priority */
#define MATRIX_PRAS4_M5PR(value) ((MATRIX_PRAS4_M5PR_Msk & ((value) << MATRIX_PRAS4_M5PR_Pos)))
/* -------- MATRIX_PRAS5 : (MATRIX Offset: 0x00A8) Priority Register A for Slave 5 -------- */
#define MATRIX_PRAS5_M0PR_Pos 0
#define MATRIX_PRAS5_M0PR_Msk (0x3u << MATRIX_PRAS5_M0PR_Pos) /**< \brief (MATRIX_PRAS5) Master 0 Priority */
#define MATRIX_PRAS5_M0PR(value) ((MATRIX_PRAS5_M0PR_Msk & ((value) << MATRIX_PRAS5_M0PR_Pos)))
#define MATRIX_PRAS5_M1PR_Pos 4
#define MATRIX_PRAS5_M1PR_Msk (0x3u << MATRIX_PRAS5_M1PR_Pos) /**< \brief (MATRIX_PRAS5) Master 1 Priority */
#define MATRIX_PRAS5_M1PR(value) ((MATRIX_PRAS5_M1PR_Msk & ((value) << MATRIX_PRAS5_M1PR_Pos)))
#define MATRIX_PRAS5_M2PR_Pos 8
#define MATRIX_PRAS5_M2PR_Msk (0x3u << MATRIX_PRAS5_M2PR_Pos) /**< \brief (MATRIX_PRAS5) Master 2 Priority */
#define MATRIX_PRAS5_M2PR(value) ((MATRIX_PRAS5_M2PR_Msk & ((value) << MATRIX_PRAS5_M2PR_Pos)))
#define MATRIX_PRAS5_M3PR_Pos 12
#define MATRIX_PRAS5_M3PR_Msk (0x3u << MATRIX_PRAS5_M3PR_Pos) /**< \brief (MATRIX_PRAS5) Master 3 Priority */
#define MATRIX_PRAS5_M3PR(value) ((MATRIX_PRAS5_M3PR_Msk & ((value) << MATRIX_PRAS5_M3PR_Pos)))
#define MATRIX_PRAS5_M4PR_Pos 16
#define MATRIX_PRAS5_M4PR_Msk (0x3u << MATRIX_PRAS5_M4PR_Pos) /**< \brief (MATRIX_PRAS5) Master 4 Priority */
#define MATRIX_PRAS5_M4PR(value) ((MATRIX_PRAS5_M4PR_Msk & ((value) << MATRIX_PRAS5_M4PR_Pos)))
#define MATRIX_PRAS5_M5PR_Pos 20
#define MATRIX_PRAS5_M5PR_Msk (0x3u << MATRIX_PRAS5_M5PR_Pos) /**< \brief (MATRIX_PRAS5) Master 5 Priority */
#define MATRIX_PRAS5_M5PR(value) ((MATRIX_PRAS5_M5PR_Msk & ((value) << MATRIX_PRAS5_M5PR_Pos)))
/* -------- MATRIX_PRAS6 : (MATRIX Offset: 0x00B0) Priority Register A for Slave 6 -------- */
#define MATRIX_PRAS6_M0PR_Pos 0
#define MATRIX_PRAS6_M0PR_Msk (0x3u << MATRIX_PRAS6_M0PR_Pos) /**< \brief (MATRIX_PRAS6) Master 0 Priority */
#define MATRIX_PRAS6_M0PR(value) ((MATRIX_PRAS6_M0PR_Msk & ((value) << MATRIX_PRAS6_M0PR_Pos)))
#define MATRIX_PRAS6_M1PR_Pos 4
#define MATRIX_PRAS6_M1PR_Msk (0x3u << MATRIX_PRAS6_M1PR_Pos) /**< \brief (MATRIX_PRAS6) Master 1 Priority */
#define MATRIX_PRAS6_M1PR(value) ((MATRIX_PRAS6_M1PR_Msk & ((value) << MATRIX_PRAS6_M1PR_Pos)))
#define MATRIX_PRAS6_M2PR_Pos 8
#define MATRIX_PRAS6_M2PR_Msk (0x3u << MATRIX_PRAS6_M2PR_Pos) /**< \brief (MATRIX_PRAS6) Master 2 Priority */
#define MATRIX_PRAS6_M2PR(value) ((MATRIX_PRAS6_M2PR_Msk & ((value) << MATRIX_PRAS6_M2PR_Pos)))
#define MATRIX_PRAS6_M3PR_Pos 12
#define MATRIX_PRAS6_M3PR_Msk (0x3u << MATRIX_PRAS6_M3PR_Pos) /**< \brief (MATRIX_PRAS6) Master 3 Priority */
#define MATRIX_PRAS6_M3PR(value) ((MATRIX_PRAS6_M3PR_Msk & ((value) << MATRIX_PRAS6_M3PR_Pos)))
#define MATRIX_PRAS6_M4PR_Pos 16
#define MATRIX_PRAS6_M4PR_Msk (0x3u << MATRIX_PRAS6_M4PR_Pos) /**< \brief (MATRIX_PRAS6) Master 4 Priority */
#define MATRIX_PRAS6_M4PR(value) ((MATRIX_PRAS6_M4PR_Msk & ((value) << MATRIX_PRAS6_M4PR_Pos)))
#define MATRIX_PRAS6_M5PR_Pos 20
#define MATRIX_PRAS6_M5PR_Msk (0x3u << MATRIX_PRAS6_M5PR_Pos) /**< \brief (MATRIX_PRAS6) Master 5 Priority */
#define MATRIX_PRAS6_M5PR(value) ((MATRIX_PRAS6_M5PR_Msk & ((value) << MATRIX_PRAS6_M5PR_Pos)))
/* -------- MATRIX_PRAS7 : (MATRIX Offset: 0x00B8) Priority Register A for Slave 7 -------- */
#define MATRIX_PRAS7_M0PR_Pos 0
#define MATRIX_PRAS7_M0PR_Msk (0x3u << MATRIX_PRAS7_M0PR_Pos) /**< \brief (MATRIX_PRAS7) Master 0 Priority */
#define MATRIX_PRAS7_M0PR(value) ((MATRIX_PRAS7_M0PR_Msk & ((value) << MATRIX_PRAS7_M0PR_Pos)))
#define MATRIX_PRAS7_M1PR_Pos 4
#define MATRIX_PRAS7_M1PR_Msk (0x3u << MATRIX_PRAS7_M1PR_Pos) /**< \brief (MATRIX_PRAS7) Master 1 Priority */
#define MATRIX_PRAS7_M1PR(value) ((MATRIX_PRAS7_M1PR_Msk & ((value) << MATRIX_PRAS7_M1PR_Pos)))
#define MATRIX_PRAS7_M2PR_Pos 8
#define MATRIX_PRAS7_M2PR_Msk (0x3u << MATRIX_PRAS7_M2PR_Pos) /**< \brief (MATRIX_PRAS7) Master 2 Priority */
#define MATRIX_PRAS7_M2PR(value) ((MATRIX_PRAS7_M2PR_Msk & ((value) << MATRIX_PRAS7_M2PR_Pos)))
#define MATRIX_PRAS7_M3PR_Pos 12
#define MATRIX_PRAS7_M3PR_Msk (0x3u << MATRIX_PRAS7_M3PR_Pos) /**< \brief (MATRIX_PRAS7) Master 3 Priority */
#define MATRIX_PRAS7_M3PR(value) ((MATRIX_PRAS7_M3PR_Msk & ((value) << MATRIX_PRAS7_M3PR_Pos)))
#define MATRIX_PRAS7_M4PR_Pos 16
#define MATRIX_PRAS7_M4PR_Msk (0x3u << MATRIX_PRAS7_M4PR_Pos) /**< \brief (MATRIX_PRAS7) Master 4 Priority */
#define MATRIX_PRAS7_M4PR(value) ((MATRIX_PRAS7_M4PR_Msk & ((value) << MATRIX_PRAS7_M4PR_Pos)))
#define MATRIX_PRAS7_M5PR_Pos 20
#define MATRIX_PRAS7_M5PR_Msk (0x3u << MATRIX_PRAS7_M5PR_Pos) /**< \brief (MATRIX_PRAS7) Master 5 Priority */
#define MATRIX_PRAS7_M5PR(value) ((MATRIX_PRAS7_M5PR_Msk & ((value) << MATRIX_PRAS7_M5PR_Pos)))
/* -------- MATRIX_PRAS8 : (MATRIX Offset: 0x00C0) Priority Register A for Slave 8 -------- */
#define MATRIX_PRAS8_M0PR_Pos 0
#define MATRIX_PRAS8_M0PR_Msk (0x3u << MATRIX_PRAS8_M0PR_Pos) /**< \brief (MATRIX_PRAS8) Master 0 Priority */
#define MATRIX_PRAS8_M0PR(value) ((MATRIX_PRAS8_M0PR_Msk & ((value) << MATRIX_PRAS8_M0PR_Pos)))
#define MATRIX_PRAS8_M1PR_Pos 4
#define MATRIX_PRAS8_M1PR_Msk (0x3u << MATRIX_PRAS8_M1PR_Pos) /**< \brief (MATRIX_PRAS8) Master 1 Priority */
#define MATRIX_PRAS8_M1PR(value) ((MATRIX_PRAS8_M1PR_Msk & ((value) << MATRIX_PRAS8_M1PR_Pos)))
#define MATRIX_PRAS8_M2PR_Pos 8
#define MATRIX_PRAS8_M2PR_Msk (0x3u << MATRIX_PRAS8_M2PR_Pos) /**< \brief (MATRIX_PRAS8) Master 2 Priority */
#define MATRIX_PRAS8_M2PR(value) ((MATRIX_PRAS8_M2PR_Msk & ((value) << MATRIX_PRAS8_M2PR_Pos)))
#define MATRIX_PRAS8_M3PR_Pos 12
#define MATRIX_PRAS8_M3PR_Msk (0x3u << MATRIX_PRAS8_M3PR_Pos) /**< \brief (MATRIX_PRAS8) Master 3 Priority */
#define MATRIX_PRAS8_M3PR(value) ((MATRIX_PRAS8_M3PR_Msk & ((value) << MATRIX_PRAS8_M3PR_Pos)))
#define MATRIX_PRAS8_M4PR_Pos 16
#define MATRIX_PRAS8_M4PR_Msk (0x3u << MATRIX_PRAS8_M4PR_Pos) /**< \brief (MATRIX_PRAS8) Master 4 Priority */
#define MATRIX_PRAS8_M4PR(value) ((MATRIX_PRAS8_M4PR_Msk & ((value) << MATRIX_PRAS8_M4PR_Pos)))
#define MATRIX_PRAS8_M5PR_Pos 20
#define MATRIX_PRAS8_M5PR_Msk (0x3u << MATRIX_PRAS8_M5PR_Pos) /**< \brief (MATRIX_PRAS8) Master 5 Priority */
#define MATRIX_PRAS8_M5PR(value) ((MATRIX_PRAS8_M5PR_Msk & ((value) << MATRIX_PRAS8_M5PR_Pos)))
/* -------- MATRIX_MRCR : (MATRIX Offset: 0x0100) Master Remap Control Register -------- */
#define MATRIX_MRCR_RCB0 (0x1u << 0) /**< \brief (MATRIX_MRCR) Remap Command Bit for AHB Master 0 */
#define MATRIX_MRCR_RCB1 (0x1u << 1) /**< \brief (MATRIX_MRCR) Remap Command Bit for AHB Master 1 */
#define MATRIX_MRCR_RCB2 (0x1u << 2) /**< \brief (MATRIX_MRCR) Remap Command Bit for AHB Master 2 */
#define MATRIX_MRCR_RCB3 (0x1u << 3) /**< \brief (MATRIX_MRCR) Remap Command Bit for AHB Master 3 */
#define MATRIX_MRCR_RCB4_Pos 4
#define MATRIX_MRCR_RCB4_Msk (0x3u << MATRIX_MRCR_RCB4_Pos) /**< \brief (MATRIX_MRCR) Remap Command Bit for AHB Master 4 */
#define MATRIX_MRCR_RCB4(value) ((MATRIX_MRCR_RCB4_Msk & ((value) << MATRIX_MRCR_RCB4_Pos)))
#define MATRIX_MRCR_RCB5 (0x1u << 6) /**< \brief (MATRIX_MRCR) Remap Command Bit for AHB Master 5 */
/* -------- CCFG_SYSIO : (MATRIX Offset: 0x0114) System I/O Configuration register -------- */
#define CCFG_SYSIO_SYSIO12 (0x1u << 12) /**< \brief (CCFG_SYSIO) PC0 or ERASE Assignment */
/* -------- MATRIX_WPMR : (MATRIX Offset: 0x1E4) Write Protect Mode Register -------- */
#define MATRIX_WPMR_WPEN (0x1u << 0) /**< \brief (MATRIX_WPMR) Write Protect ENable */
#define MATRIX_WPMR_WPKEY_Pos 8
#define MATRIX_WPMR_WPKEY_Msk (0xffffffu << MATRIX_WPMR_WPKEY_Pos) /**< \brief (MATRIX_WPMR) Write Protect KEY (Write-only) */
#define MATRIX_WPMR_WPKEY(value) ((MATRIX_WPMR_WPKEY_Msk & ((value) << MATRIX_WPMR_WPKEY_Pos)))
/* -------- MATRIX_WPSR : (MATRIX Offset: 0x1E8) Write Protect Status Register -------- */
#define MATRIX_WPSR_WPVS (0x1u << 0) /**< \brief (MATRIX_WPSR) Write Protect Violation Status */
#define MATRIX_WPSR_WPVSRC_Pos 8
#define MATRIX_WPSR_WPVSRC_Msk (0xffffu << MATRIX_WPSR_WPVSRC_Pos) /**< \brief (MATRIX_WPSR) Write Protect Violation Source */
/*@}*/
#endif /* _SAM3XA_MATRIX_COMPONENT_ */

View File

@@ -0,0 +1,98 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2012, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _SAM3XA_PDC_COMPONENT_
#define _SAM3XA_PDC_COMPONENT_
/* ============================================================================= */
/** SOFTWARE API DEFINITION FOR Peripheral DMA Controller */
/* ============================================================================= */
/** \addtogroup SAM3XA_PDC Peripheral DMA Controller */
/*@{*/
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
/** \brief Pdc hardware registers */
typedef struct {
RwReg PERIPH_RPR; /**< \brief (Pdc Offset: 0x0) Receive Pointer Register */
RwReg PERIPH_RCR; /**< \brief (Pdc Offset: 0x4) Receive Counter Register */
RwReg PERIPH_TPR; /**< \brief (Pdc Offset: 0x8) Transmit Pointer Register */
RwReg PERIPH_TCR; /**< \brief (Pdc Offset: 0xC) Transmit Counter Register */
RwReg PERIPH_RNPR; /**< \brief (Pdc Offset: 0x10) Receive Next Pointer Register */
RwReg PERIPH_RNCR; /**< \brief (Pdc Offset: 0x14) Receive Next Counter Register */
RwReg PERIPH_TNPR; /**< \brief (Pdc Offset: 0x18) Transmit Next Pointer Register */
RwReg PERIPH_TNCR; /**< \brief (Pdc Offset: 0x1C) Transmit Next Counter Register */
WoReg PERIPH_PTCR; /**< \brief (Pdc Offset: 0x20) Transfer Control Register */
RoReg PERIPH_PTSR; /**< \brief (Pdc Offset: 0x24) Transfer Status Register */
} Pdc;
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
/* -------- PERIPH_RPR : (PDC Offset: 0x0) Receive Pointer Register -------- */
#define PERIPH_RPR_RXPTR_Pos 0
#define PERIPH_RPR_RXPTR_Msk (0xffffffffu << PERIPH_RPR_RXPTR_Pos) /**< \brief (PERIPH_RPR) Receive Pointer Register */
#define PERIPH_RPR_RXPTR(value) ((PERIPH_RPR_RXPTR_Msk & ((value) << PERIPH_RPR_RXPTR_Pos)))
/* -------- PERIPH_RCR : (PDC Offset: 0x4) Receive Counter Register -------- */
#define PERIPH_RCR_RXCTR_Pos 0
#define PERIPH_RCR_RXCTR_Msk (0xffffu << PERIPH_RCR_RXCTR_Pos) /**< \brief (PERIPH_RCR) Receive Counter Register */
#define PERIPH_RCR_RXCTR(value) ((PERIPH_RCR_RXCTR_Msk & ((value) << PERIPH_RCR_RXCTR_Pos)))
/* -------- PERIPH_TPR : (PDC Offset: 0x8) Transmit Pointer Register -------- */
#define PERIPH_TPR_TXPTR_Pos 0
#define PERIPH_TPR_TXPTR_Msk (0xffffffffu << PERIPH_TPR_TXPTR_Pos) /**< \brief (PERIPH_TPR) Transmit Counter Register */
#define PERIPH_TPR_TXPTR(value) ((PERIPH_TPR_TXPTR_Msk & ((value) << PERIPH_TPR_TXPTR_Pos)))
/* -------- PERIPH_TCR : (PDC Offset: 0xC) Transmit Counter Register -------- */
#define PERIPH_TCR_TXCTR_Pos 0
#define PERIPH_TCR_TXCTR_Msk (0xffffu << PERIPH_TCR_TXCTR_Pos) /**< \brief (PERIPH_TCR) Transmit Counter Register */
#define PERIPH_TCR_TXCTR(value) ((PERIPH_TCR_TXCTR_Msk & ((value) << PERIPH_TCR_TXCTR_Pos)))
/* -------- PERIPH_RNPR : (PDC Offset: 0x10) Receive Next Pointer Register -------- */
#define PERIPH_RNPR_RXNPTR_Pos 0
#define PERIPH_RNPR_RXNPTR_Msk (0xffffffffu << PERIPH_RNPR_RXNPTR_Pos) /**< \brief (PERIPH_RNPR) Receive Next Pointer */
#define PERIPH_RNPR_RXNPTR(value) ((PERIPH_RNPR_RXNPTR_Msk & ((value) << PERIPH_RNPR_RXNPTR_Pos)))
/* -------- PERIPH_RNCR : (PDC Offset: 0x14) Receive Next Counter Register -------- */
#define PERIPH_RNCR_RXNCTR_Pos 0
#define PERIPH_RNCR_RXNCTR_Msk (0xffffu << PERIPH_RNCR_RXNCTR_Pos) /**< \brief (PERIPH_RNCR) Receive Next Counter */
#define PERIPH_RNCR_RXNCTR(value) ((PERIPH_RNCR_RXNCTR_Msk & ((value) << PERIPH_RNCR_RXNCTR_Pos)))
/* -------- PERIPH_TNPR : (PDC Offset: 0x18) Transmit Next Pointer Register -------- */
#define PERIPH_TNPR_TXNPTR_Pos 0
#define PERIPH_TNPR_TXNPTR_Msk (0xffffffffu << PERIPH_TNPR_TXNPTR_Pos) /**< \brief (PERIPH_TNPR) Transmit Next Pointer */
#define PERIPH_TNPR_TXNPTR(value) ((PERIPH_TNPR_TXNPTR_Msk & ((value) << PERIPH_TNPR_TXNPTR_Pos)))
/* -------- PERIPH_TNCR : (PDC Offset: 0x1C) Transmit Next Counter Register -------- */
#define PERIPH_TNCR_TXNCTR_Pos 0
#define PERIPH_TNCR_TXNCTR_Msk (0xffffu << PERIPH_TNCR_TXNCTR_Pos) /**< \brief (PERIPH_TNCR) Transmit Counter Next */
#define PERIPH_TNCR_TXNCTR(value) ((PERIPH_TNCR_TXNCTR_Msk & ((value) << PERIPH_TNCR_TXNCTR_Pos)))
/* -------- PERIPH_PTCR : (PDC Offset: 0x20) Transfer Control Register -------- */
#define PERIPH_PTCR_RXTEN (0x1u << 0) /**< \brief (PERIPH_PTCR) Receiver Transfer Enable */
#define PERIPH_PTCR_RXTDIS (0x1u << 1) /**< \brief (PERIPH_PTCR) Receiver Transfer Disable */
#define PERIPH_PTCR_TXTEN (0x1u << 8) /**< \brief (PERIPH_PTCR) Transmitter Transfer Enable */
#define PERIPH_PTCR_TXTDIS (0x1u << 9) /**< \brief (PERIPH_PTCR) Transmitter Transfer Disable */
/* -------- PERIPH_PTSR : (PDC Offset: 0x24) Transfer Status Register -------- */
#define PERIPH_PTSR_RXTEN (0x1u << 0) /**< \brief (PERIPH_PTSR) Receiver Transfer Enable */
#define PERIPH_PTSR_TXTEN (0x1u << 8) /**< \brief (PERIPH_PTSR) Transmitter Transfer Enable */
/*@}*/
#endif /* _SAM3XA_PDC_COMPONENT_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,416 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2012, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _SAM3XA_PMC_COMPONENT_
#define _SAM3XA_PMC_COMPONENT_
/* ============================================================================= */
/** SOFTWARE API DEFINITION FOR Power Management Controller */
/* ============================================================================= */
/** \addtogroup SAM3XA_PMC Power Management Controller */
/*@{*/
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
/** \brief Pmc hardware registers */
typedef struct {
WoReg PMC_SCER; /**< \brief (Pmc Offset: 0x0000) System Clock Enable Register */
WoReg PMC_SCDR; /**< \brief (Pmc Offset: 0x0004) System Clock Disable Register */
RoReg PMC_SCSR; /**< \brief (Pmc Offset: 0x0008) System Clock Status Register */
RoReg Reserved1[1];
WoReg PMC_PCER0; /**< \brief (Pmc Offset: 0x0010) Peripheral Clock Enable Register 0 */
WoReg PMC_PCDR0; /**< \brief (Pmc Offset: 0x0014) Peripheral Clock Disable Register 0 */
RoReg PMC_PCSR0; /**< \brief (Pmc Offset: 0x0018) Peripheral Clock Status Register 0 */
RwReg CKGR_UCKR; /**< \brief (Pmc Offset: 0x001C) UTMI Clock Register */
RwReg CKGR_MOR; /**< \brief (Pmc Offset: 0x0020) Main Oscillator Register */
RoReg CKGR_MCFR; /**< \brief (Pmc Offset: 0x0024) Main Clock Frequency Register */
RwReg CKGR_PLLAR; /**< \brief (Pmc Offset: 0x0028) PLLA Register */
RoReg Reserved2[1];
RwReg PMC_MCKR; /**< \brief (Pmc Offset: 0x0030) Master Clock Register */
RoReg Reserved3[1];
RwReg PMC_USB; /**< \brief (Pmc Offset: 0x0038) USB Clock Register */
RoReg Reserved4[1];
RwReg PMC_PCK[3]; /**< \brief (Pmc Offset: 0x0040) Programmable Clock 0 Register */
RoReg Reserved5[5];
WoReg PMC_IER; /**< \brief (Pmc Offset: 0x0060) Interrupt Enable Register */
WoReg PMC_IDR; /**< \brief (Pmc Offset: 0x0064) Interrupt Disable Register */
RoReg PMC_SR; /**< \brief (Pmc Offset: 0x0068) Status Register */
RoReg PMC_IMR; /**< \brief (Pmc Offset: 0x006C) Interrupt Mask Register */
RwReg PMC_FSMR; /**< \brief (Pmc Offset: 0x0070) Fast Startup Mode Register */
RwReg PMC_FSPR; /**< \brief (Pmc Offset: 0x0074) Fast Startup Polarity Register */
WoReg PMC_FOCR; /**< \brief (Pmc Offset: 0x0078) Fault Output Clear Register */
RoReg Reserved6[26];
RwReg PMC_WPMR; /**< \brief (Pmc Offset: 0x00E4) Write Protect Mode Register */
RoReg PMC_WPSR; /**< \brief (Pmc Offset: 0x00E8) Write Protect Status Register */
RoReg Reserved7[5];
WoReg PMC_PCER1; /**< \brief (Pmc Offset: 0x0100) Peripheral Clock Enable Register 1 */
WoReg PMC_PCDR1; /**< \brief (Pmc Offset: 0x0104) Peripheral Clock Disable Register 1 */
RoReg PMC_PCSR1; /**< \brief (Pmc Offset: 0x0108) Peripheral Clock Status Register 1 */
RwReg PMC_PCR; /**< \brief (Pmc Offset: 0x010C) Peripheral Control Register */
} Pmc;
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
/* -------- PMC_SCER : (PMC Offset: 0x0000) System Clock Enable Register -------- */
#define PMC_SCER_UOTGCLK (0x1u << 5) /**< \brief (PMC_SCER) Enable USB OTG Clock (48 MHz, USB_48M) for UTMI */
#define PMC_SCER_PCK0 (0x1u << 8) /**< \brief (PMC_SCER) Programmable Clock 0 Output Enable */
#define PMC_SCER_PCK1 (0x1u << 9) /**< \brief (PMC_SCER) Programmable Clock 1 Output Enable */
#define PMC_SCER_PCK2 (0x1u << 10) /**< \brief (PMC_SCER) Programmable Clock 2 Output Enable */
/* -------- PMC_SCDR : (PMC Offset: 0x0004) System Clock Disable Register -------- */
#define PMC_SCDR_UOTGCLK (0x1u << 5) /**< \brief (PMC_SCDR) Disable USB OTG Clock (48 MHz, USB_48M) for UTMI */
#define PMC_SCDR_PCK0 (0x1u << 8) /**< \brief (PMC_SCDR) Programmable Clock 0 Output Disable */
#define PMC_SCDR_PCK1 (0x1u << 9) /**< \brief (PMC_SCDR) Programmable Clock 1 Output Disable */
#define PMC_SCDR_PCK2 (0x1u << 10) /**< \brief (PMC_SCDR) Programmable Clock 2 Output Disable */
/* -------- PMC_SCSR : (PMC Offset: 0x0008) System Clock Status Register -------- */
#define PMC_SCSR_UOTGCLK (0x1u << 5) /**< \brief (PMC_SCSR) USB OTG Clock (48 MHz, USB_48M) Clock Status */
#define PMC_SCSR_PCK0 (0x1u << 8) /**< \brief (PMC_SCSR) Programmable Clock 0 Output Status */
#define PMC_SCSR_PCK1 (0x1u << 9) /**< \brief (PMC_SCSR) Programmable Clock 1 Output Status */
#define PMC_SCSR_PCK2 (0x1u << 10) /**< \brief (PMC_SCSR) Programmable Clock 2 Output Status */
/* -------- PMC_PCER0 : (PMC Offset: 0x0010) Peripheral Clock Enable Register 0 -------- */
#define PMC_PCER0_PID2 (0x1u << 2) /**< \brief (PMC_PCER0) Peripheral Clock 2 Enable */
#define PMC_PCER0_PID3 (0x1u << 3) /**< \brief (PMC_PCER0) Peripheral Clock 3 Enable */
#define PMC_PCER0_PID4 (0x1u << 4) /**< \brief (PMC_PCER0) Peripheral Clock 4 Enable */
#define PMC_PCER0_PID5 (0x1u << 5) /**< \brief (PMC_PCER0) Peripheral Clock 5 Enable */
#define PMC_PCER0_PID6 (0x1u << 6) /**< \brief (PMC_PCER0) Peripheral Clock 6 Enable */
#define PMC_PCER0_PID7 (0x1u << 7) /**< \brief (PMC_PCER0) Peripheral Clock 7 Enable */
#define PMC_PCER0_PID8 (0x1u << 8) /**< \brief (PMC_PCER0) Peripheral Clock 8 Enable */
#define PMC_PCER0_PID9 (0x1u << 9) /**< \brief (PMC_PCER0) Peripheral Clock 9 Enable */
#define PMC_PCER0_PID10 (0x1u << 10) /**< \brief (PMC_PCER0) Peripheral Clock 10 Enable */
#define PMC_PCER0_PID11 (0x1u << 11) /**< \brief (PMC_PCER0) Peripheral Clock 11 Enable */
#define PMC_PCER0_PID12 (0x1u << 12) /**< \brief (PMC_PCER0) Peripheral Clock 12 Enable */
#define PMC_PCER0_PID13 (0x1u << 13) /**< \brief (PMC_PCER0) Peripheral Clock 13 Enable */
#define PMC_PCER0_PID14 (0x1u << 14) /**< \brief (PMC_PCER0) Peripheral Clock 14 Enable */
#define PMC_PCER0_PID15 (0x1u << 15) /**< \brief (PMC_PCER0) Peripheral Clock 15 Enable */
#define PMC_PCER0_PID16 (0x1u << 16) /**< \brief (PMC_PCER0) Peripheral Clock 16 Enable */
#define PMC_PCER0_PID17 (0x1u << 17) /**< \brief (PMC_PCER0) Peripheral Clock 17 Enable */
#define PMC_PCER0_PID18 (0x1u << 18) /**< \brief (PMC_PCER0) Peripheral Clock 18 Enable */
#define PMC_PCER0_PID19 (0x1u << 19) /**< \brief (PMC_PCER0) Peripheral Clock 19 Enable */
#define PMC_PCER0_PID20 (0x1u << 20) /**< \brief (PMC_PCER0) Peripheral Clock 20 Enable */
#define PMC_PCER0_PID21 (0x1u << 21) /**< \brief (PMC_PCER0) Peripheral Clock 21 Enable */
#define PMC_PCER0_PID22 (0x1u << 22) /**< \brief (PMC_PCER0) Peripheral Clock 22 Enable */
#define PMC_PCER0_PID23 (0x1u << 23) /**< \brief (PMC_PCER0) Peripheral Clock 23 Enable */
#define PMC_PCER0_PID24 (0x1u << 24) /**< \brief (PMC_PCER0) Peripheral Clock 24 Enable */
#define PMC_PCER0_PID25 (0x1u << 25) /**< \brief (PMC_PCER0) Peripheral Clock 25 Enable */
#define PMC_PCER0_PID26 (0x1u << 26) /**< \brief (PMC_PCER0) Peripheral Clock 26 Enable */
#define PMC_PCER0_PID27 (0x1u << 27) /**< \brief (PMC_PCER0) Peripheral Clock 27 Enable */
#define PMC_PCER0_PID28 (0x1u << 28) /**< \brief (PMC_PCER0) Peripheral Clock 28 Enable */
#define PMC_PCER0_PID29 (0x1u << 29) /**< \brief (PMC_PCER0) Peripheral Clock 29 Enable */
#define PMC_PCER0_PID30 (0x1u << 30) /**< \brief (PMC_PCER0) Peripheral Clock 30 Enable */
#define PMC_PCER0_PID31 (0x1u << 31) /**< \brief (PMC_PCER0) Peripheral Clock 31 Enable */
/* -------- PMC_PCDR0 : (PMC Offset: 0x0014) Peripheral Clock Disable Register 0 -------- */
#define PMC_PCDR0_PID2 (0x1u << 2) /**< \brief (PMC_PCDR0) Peripheral Clock 2 Disable */
#define PMC_PCDR0_PID3 (0x1u << 3) /**< \brief (PMC_PCDR0) Peripheral Clock 3 Disable */
#define PMC_PCDR0_PID4 (0x1u << 4) /**< \brief (PMC_PCDR0) Peripheral Clock 4 Disable */
#define PMC_PCDR0_PID5 (0x1u << 5) /**< \brief (PMC_PCDR0) Peripheral Clock 5 Disable */
#define PMC_PCDR0_PID6 (0x1u << 6) /**< \brief (PMC_PCDR0) Peripheral Clock 6 Disable */
#define PMC_PCDR0_PID7 (0x1u << 7) /**< \brief (PMC_PCDR0) Peripheral Clock 7 Disable */
#define PMC_PCDR0_PID8 (0x1u << 8) /**< \brief (PMC_PCDR0) Peripheral Clock 8 Disable */
#define PMC_PCDR0_PID9 (0x1u << 9) /**< \brief (PMC_PCDR0) Peripheral Clock 9 Disable */
#define PMC_PCDR0_PID10 (0x1u << 10) /**< \brief (PMC_PCDR0) Peripheral Clock 10 Disable */
#define PMC_PCDR0_PID11 (0x1u << 11) /**< \brief (PMC_PCDR0) Peripheral Clock 11 Disable */
#define PMC_PCDR0_PID12 (0x1u << 12) /**< \brief (PMC_PCDR0) Peripheral Clock 12 Disable */
#define PMC_PCDR0_PID13 (0x1u << 13) /**< \brief (PMC_PCDR0) Peripheral Clock 13 Disable */
#define PMC_PCDR0_PID14 (0x1u << 14) /**< \brief (PMC_PCDR0) Peripheral Clock 14 Disable */
#define PMC_PCDR0_PID15 (0x1u << 15) /**< \brief (PMC_PCDR0) Peripheral Clock 15 Disable */
#define PMC_PCDR0_PID16 (0x1u << 16) /**< \brief (PMC_PCDR0) Peripheral Clock 16 Disable */
#define PMC_PCDR0_PID17 (0x1u << 17) /**< \brief (PMC_PCDR0) Peripheral Clock 17 Disable */
#define PMC_PCDR0_PID18 (0x1u << 18) /**< \brief (PMC_PCDR0) Peripheral Clock 18 Disable */
#define PMC_PCDR0_PID19 (0x1u << 19) /**< \brief (PMC_PCDR0) Peripheral Clock 19 Disable */
#define PMC_PCDR0_PID20 (0x1u << 20) /**< \brief (PMC_PCDR0) Peripheral Clock 20 Disable */
#define PMC_PCDR0_PID21 (0x1u << 21) /**< \brief (PMC_PCDR0) Peripheral Clock 21 Disable */
#define PMC_PCDR0_PID22 (0x1u << 22) /**< \brief (PMC_PCDR0) Peripheral Clock 22 Disable */
#define PMC_PCDR0_PID23 (0x1u << 23) /**< \brief (PMC_PCDR0) Peripheral Clock 23 Disable */
#define PMC_PCDR0_PID24 (0x1u << 24) /**< \brief (PMC_PCDR0) Peripheral Clock 24 Disable */
#define PMC_PCDR0_PID25 (0x1u << 25) /**< \brief (PMC_PCDR0) Peripheral Clock 25 Disable */
#define PMC_PCDR0_PID26 (0x1u << 26) /**< \brief (PMC_PCDR0) Peripheral Clock 26 Disable */
#define PMC_PCDR0_PID27 (0x1u << 27) /**< \brief (PMC_PCDR0) Peripheral Clock 27 Disable */
#define PMC_PCDR0_PID28 (0x1u << 28) /**< \brief (PMC_PCDR0) Peripheral Clock 28 Disable */
#define PMC_PCDR0_PID29 (0x1u << 29) /**< \brief (PMC_PCDR0) Peripheral Clock 29 Disable */
#define PMC_PCDR0_PID30 (0x1u << 30) /**< \brief (PMC_PCDR0) Peripheral Clock 30 Disable */
#define PMC_PCDR0_PID31 (0x1u << 31) /**< \brief (PMC_PCDR0) Peripheral Clock 31 Disable */
/* -------- PMC_PCSR0 : (PMC Offset: 0x0018) Peripheral Clock Status Register 0 -------- */
#define PMC_PCSR0_PID2 (0x1u << 2) /**< \brief (PMC_PCSR0) Peripheral Clock 2 Status */
#define PMC_PCSR0_PID3 (0x1u << 3) /**< \brief (PMC_PCSR0) Peripheral Clock 3 Status */
#define PMC_PCSR0_PID4 (0x1u << 4) /**< \brief (PMC_PCSR0) Peripheral Clock 4 Status */
#define PMC_PCSR0_PID5 (0x1u << 5) /**< \brief (PMC_PCSR0) Peripheral Clock 5 Status */
#define PMC_PCSR0_PID6 (0x1u << 6) /**< \brief (PMC_PCSR0) Peripheral Clock 6 Status */
#define PMC_PCSR0_PID7 (0x1u << 7) /**< \brief (PMC_PCSR0) Peripheral Clock 7 Status */
#define PMC_PCSR0_PID8 (0x1u << 8) /**< \brief (PMC_PCSR0) Peripheral Clock 8 Status */
#define PMC_PCSR0_PID9 (0x1u << 9) /**< \brief (PMC_PCSR0) Peripheral Clock 9 Status */
#define PMC_PCSR0_PID10 (0x1u << 10) /**< \brief (PMC_PCSR0) Peripheral Clock 10 Status */
#define PMC_PCSR0_PID11 (0x1u << 11) /**< \brief (PMC_PCSR0) Peripheral Clock 11 Status */
#define PMC_PCSR0_PID12 (0x1u << 12) /**< \brief (PMC_PCSR0) Peripheral Clock 12 Status */
#define PMC_PCSR0_PID13 (0x1u << 13) /**< \brief (PMC_PCSR0) Peripheral Clock 13 Status */
#define PMC_PCSR0_PID14 (0x1u << 14) /**< \brief (PMC_PCSR0) Peripheral Clock 14 Status */
#define PMC_PCSR0_PID15 (0x1u << 15) /**< \brief (PMC_PCSR0) Peripheral Clock 15 Status */
#define PMC_PCSR0_PID16 (0x1u << 16) /**< \brief (PMC_PCSR0) Peripheral Clock 16 Status */
#define PMC_PCSR0_PID17 (0x1u << 17) /**< \brief (PMC_PCSR0) Peripheral Clock 17 Status */
#define PMC_PCSR0_PID18 (0x1u << 18) /**< \brief (PMC_PCSR0) Peripheral Clock 18 Status */
#define PMC_PCSR0_PID19 (0x1u << 19) /**< \brief (PMC_PCSR0) Peripheral Clock 19 Status */
#define PMC_PCSR0_PID20 (0x1u << 20) /**< \brief (PMC_PCSR0) Peripheral Clock 20 Status */
#define PMC_PCSR0_PID21 (0x1u << 21) /**< \brief (PMC_PCSR0) Peripheral Clock 21 Status */
#define PMC_PCSR0_PID22 (0x1u << 22) /**< \brief (PMC_PCSR0) Peripheral Clock 22 Status */
#define PMC_PCSR0_PID23 (0x1u << 23) /**< \brief (PMC_PCSR0) Peripheral Clock 23 Status */
#define PMC_PCSR0_PID24 (0x1u << 24) /**< \brief (PMC_PCSR0) Peripheral Clock 24 Status */
#define PMC_PCSR0_PID25 (0x1u << 25) /**< \brief (PMC_PCSR0) Peripheral Clock 25 Status */
#define PMC_PCSR0_PID26 (0x1u << 26) /**< \brief (PMC_PCSR0) Peripheral Clock 26 Status */
#define PMC_PCSR0_PID27 (0x1u << 27) /**< \brief (PMC_PCSR0) Peripheral Clock 27 Status */
#define PMC_PCSR0_PID28 (0x1u << 28) /**< \brief (PMC_PCSR0) Peripheral Clock 28 Status */
#define PMC_PCSR0_PID29 (0x1u << 29) /**< \brief (PMC_PCSR0) Peripheral Clock 29 Status */
#define PMC_PCSR0_PID30 (0x1u << 30) /**< \brief (PMC_PCSR0) Peripheral Clock 30 Status */
#define PMC_PCSR0_PID31 (0x1u << 31) /**< \brief (PMC_PCSR0) Peripheral Clock 31 Status */
/* -------- CKGR_UCKR : (PMC Offset: 0x001C) UTMI Clock Register -------- */
#define CKGR_UCKR_UPLLEN (0x1u << 16) /**< \brief (CKGR_UCKR) UTMI PLL Enable */
#define CKGR_UCKR_UPLLCOUNT_Pos 20
#define CKGR_UCKR_UPLLCOUNT_Msk (0xfu << CKGR_UCKR_UPLLCOUNT_Pos) /**< \brief (CKGR_UCKR) UTMI PLL Start-up Time */
#define CKGR_UCKR_UPLLCOUNT(value) ((CKGR_UCKR_UPLLCOUNT_Msk & ((value) << CKGR_UCKR_UPLLCOUNT_Pos)))
/* -------- CKGR_MOR : (PMC Offset: 0x0020) Main Oscillator Register -------- */
#define CKGR_MOR_MOSCXTEN (0x1u << 0) /**< \brief (CKGR_MOR) Main Crystal Oscillator Enable */
#define CKGR_MOR_MOSCXTBY (0x1u << 1) /**< \brief (CKGR_MOR) Main Crystal Oscillator Bypass */
#define CKGR_MOR_MOSCRCEN (0x1u << 3) /**< \brief (CKGR_MOR) Main On-Chip RC Oscillator Enable */
#define CKGR_MOR_MOSCRCF_Pos 4
#define CKGR_MOR_MOSCRCF_Msk (0x7u << CKGR_MOR_MOSCRCF_Pos) /**< \brief (CKGR_MOR) Main On-Chip RC Oscillator Frequency Selection */
#define CKGR_MOR_MOSCRCF_4_MHz (0x0u << 4) /**< \brief (CKGR_MOR) The Fast RC Oscillator Frequency is at 4 MHz (default) */
#define CKGR_MOR_MOSCRCF_8_MHz (0x1u << 4) /**< \brief (CKGR_MOR) The Fast RC Oscillator Frequency is at 8 MHz */
#define CKGR_MOR_MOSCRCF_12_MHz (0x2u << 4) /**< \brief (CKGR_MOR) The Fast RC Oscillator Frequency is at 12 MHz */
#define CKGR_MOR_MOSCXTST_Pos 8
#define CKGR_MOR_MOSCXTST_Msk (0xffu << CKGR_MOR_MOSCXTST_Pos) /**< \brief (CKGR_MOR) Main Crystal Oscillator Start-up Time */
#define CKGR_MOR_MOSCXTST(value) ((CKGR_MOR_MOSCXTST_Msk & ((value) << CKGR_MOR_MOSCXTST_Pos)))
#define CKGR_MOR_KEY_Pos 16
#define CKGR_MOR_KEY_Msk (0xffu << CKGR_MOR_KEY_Pos) /**< \brief (CKGR_MOR) Password */
#define CKGR_MOR_KEY(value) ((CKGR_MOR_KEY_Msk & ((value) << CKGR_MOR_KEY_Pos)))
#define CKGR_MOR_MOSCSEL (0x1u << 24) /**< \brief (CKGR_MOR) Main Oscillator Selection */
#define CKGR_MOR_CFDEN (0x1u << 25) /**< \brief (CKGR_MOR) Clock Failure Detector Enable */
/* -------- CKGR_MCFR : (PMC Offset: 0x0024) Main Clock Frequency Register -------- */
#define CKGR_MCFR_MAINF_Pos 0
#define CKGR_MCFR_MAINF_Msk (0xffffu << CKGR_MCFR_MAINF_Pos) /**< \brief (CKGR_MCFR) Main Clock Frequency */
#define CKGR_MCFR_MAINFRDY (0x1u << 16) /**< \brief (CKGR_MCFR) Main Clock Ready */
/* -------- CKGR_PLLAR : (PMC Offset: 0x0028) PLLA Register -------- */
#define CKGR_PLLAR_DIVA_Pos 0
#define CKGR_PLLAR_DIVA_Msk (0xffu << CKGR_PLLAR_DIVA_Pos) /**< \brief (CKGR_PLLAR) Divider */
#define CKGR_PLLAR_DIVA(value) ((CKGR_PLLAR_DIVA_Msk & ((value) << CKGR_PLLAR_DIVA_Pos)))
#define CKGR_PLLAR_PLLACOUNT_Pos 8
#define CKGR_PLLAR_PLLACOUNT_Msk (0x3fu << CKGR_PLLAR_PLLACOUNT_Pos) /**< \brief (CKGR_PLLAR) PLLA Counter */
#define CKGR_PLLAR_PLLACOUNT(value) ((CKGR_PLLAR_PLLACOUNT_Msk & ((value) << CKGR_PLLAR_PLLACOUNT_Pos)))
#define CKGR_PLLAR_MULA_Pos 16
#define CKGR_PLLAR_MULA_Msk (0x7ffu << CKGR_PLLAR_MULA_Pos) /**< \brief (CKGR_PLLAR) PLLA Multiplier */
#define CKGR_PLLAR_MULA(value) ((CKGR_PLLAR_MULA_Msk & ((value) << CKGR_PLLAR_MULA_Pos)))
#define CKGR_PLLAR_ONE (0x1u << 29) /**< \brief (CKGR_PLLAR) Must Be Set to 1 */
/* -------- PMC_MCKR : (PMC Offset: 0x0030) Master Clock Register -------- */
#define PMC_MCKR_CSS_Pos 0
#define PMC_MCKR_CSS_Msk (0x3u << PMC_MCKR_CSS_Pos) /**< \brief (PMC_MCKR) Master Clock Source Selection */
#define PMC_MCKR_CSS_SLOW_CLK (0x0u << 0) /**< \brief (PMC_MCKR) Slow Clock is selected */
#define PMC_MCKR_CSS_MAIN_CLK (0x1u << 0) /**< \brief (PMC_MCKR) Main Clock is selected */
#define PMC_MCKR_CSS_PLLA_CLK (0x2u << 0) /**< \brief (PMC_MCKR) PLLA Clock is selected */
#define PMC_MCKR_CSS_UPLL_CLK (0x3u << 0) /**< \brief (PMC_MCKR) UPLL Clock is selected */
#define PMC_MCKR_PRES_Pos 4
#define PMC_MCKR_PRES_Msk (0x7u << PMC_MCKR_PRES_Pos) /**< \brief (PMC_MCKR) Processor Clock Prescaler */
#define PMC_MCKR_PRES_CLK_1 (0x0u << 4) /**< \brief (PMC_MCKR) Selected clock */
#define PMC_MCKR_PRES_CLK_2 (0x1u << 4) /**< \brief (PMC_MCKR) Selected clock divided by 2 */
#define PMC_MCKR_PRES_CLK_4 (0x2u << 4) /**< \brief (PMC_MCKR) Selected clock divided by 4 */
#define PMC_MCKR_PRES_CLK_8 (0x3u << 4) /**< \brief (PMC_MCKR) Selected clock divided by 8 */
#define PMC_MCKR_PRES_CLK_16 (0x4u << 4) /**< \brief (PMC_MCKR) Selected clock divided by 16 */
#define PMC_MCKR_PRES_CLK_32 (0x5u << 4) /**< \brief (PMC_MCKR) Selected clock divided by 32 */
#define PMC_MCKR_PRES_CLK_64 (0x6u << 4) /**< \brief (PMC_MCKR) Selected clock divided by 64 */
#define PMC_MCKR_PRES_CLK_3 (0x7u << 4) /**< \brief (PMC_MCKR) Selected clock divided by 3 */
#define PMC_MCKR_PLLADIV2 (0x1u << 12) /**< \brief (PMC_MCKR) PLLA Divisor by 2 */
#define PMC_MCKR_UPLLDIV2 (0x1u << 13) /**< \brief (PMC_MCKR) */
/* -------- PMC_USB : (PMC Offset: 0x0038) USB Clock Register -------- */
#define PMC_USB_USBS (0x1u << 0) /**< \brief (PMC_USB) USB Input Clock Selection */
#define PMC_USB_USBDIV_Pos 8
#define PMC_USB_USBDIV_Msk (0xfu << PMC_USB_USBDIV_Pos) /**< \brief (PMC_USB) Divider for USB Clock. */
#define PMC_USB_USBDIV(value) ((PMC_USB_USBDIV_Msk & ((value) << PMC_USB_USBDIV_Pos)))
/* -------- PMC_PCK[3] : (PMC Offset: 0x0040) Programmable Clock 0 Register -------- */
#define PMC_PCK_CSS_Pos 0
#define PMC_PCK_CSS_Msk (0x7u << PMC_PCK_CSS_Pos) /**< \brief (PMC_PCK[3]) Master Clock Source Selection */
#define PMC_PCK_CSS_SLOW_CLK (0x0u << 0) /**< \brief (PMC_PCK[3]) Slow Clock is selected */
#define PMC_PCK_CSS_MAIN_CLK (0x1u << 0) /**< \brief (PMC_PCK[3]) Main Clock is selected */
#define PMC_PCK_CSS_PLLA_CLK (0x2u << 0) /**< \brief (PMC_PCK[3]) PLLA Clock is selected */
#define PMC_PCK_CSS_UPLL_CLK (0x3u << 0) /**< \brief (PMC_PCK[3]) UPLL Clock is selected */
#define PMC_PCK_CSS_MCK (0x4u << 0) /**< \brief (PMC_PCK[3]) Master Clock is selected */
#define PMC_PCK_PRES_Pos 4
#define PMC_PCK_PRES_Msk (0x7u << PMC_PCK_PRES_Pos) /**< \brief (PMC_PCK[3]) Programmable Clock Prescaler */
#define PMC_PCK_PRES_CLK_1 (0x0u << 4) /**< \brief (PMC_PCK[3]) Selected clock */
#define PMC_PCK_PRES_CLK_2 (0x1u << 4) /**< \brief (PMC_PCK[3]) Selected clock divided by 2 */
#define PMC_PCK_PRES_CLK_4 (0x2u << 4) /**< \brief (PMC_PCK[3]) Selected clock divided by 4 */
#define PMC_PCK_PRES_CLK_8 (0x3u << 4) /**< \brief (PMC_PCK[3]) Selected clock divided by 8 */
#define PMC_PCK_PRES_CLK_16 (0x4u << 4) /**< \brief (PMC_PCK[3]) Selected clock divided by 16 */
#define PMC_PCK_PRES_CLK_32 (0x5u << 4) /**< \brief (PMC_PCK[3]) Selected clock divided by 32 */
#define PMC_PCK_PRES_CLK_64 (0x6u << 4) /**< \brief (PMC_PCK[3]) Selected clock divided by 64 */
/* -------- PMC_IER : (PMC Offset: 0x0060) Interrupt Enable Register -------- */
#define PMC_IER_MOSCXTS (0x1u << 0) /**< \brief (PMC_IER) Main Crystal Oscillator Status Interrupt Enable */
#define PMC_IER_LOCKA (0x1u << 1) /**< \brief (PMC_IER) PLLA Lock Interrupt Enable */
#define PMC_IER_MCKRDY (0x1u << 3) /**< \brief (PMC_IER) Master Clock Ready Interrupt Enable */
#define PMC_IER_LOCKU (0x1u << 6) /**< \brief (PMC_IER) UTMI PLL Lock Interrupt Enable */
#define PMC_IER_PCKRDY0 (0x1u << 8) /**< \brief (PMC_IER) Programmable Clock Ready 0 Interrupt Enable */
#define PMC_IER_PCKRDY1 (0x1u << 9) /**< \brief (PMC_IER) Programmable Clock Ready 1 Interrupt Enable */
#define PMC_IER_PCKRDY2 (0x1u << 10) /**< \brief (PMC_IER) Programmable Clock Ready 2 Interrupt Enable */
#define PMC_IER_MOSCSELS (0x1u << 16) /**< \brief (PMC_IER) Main Oscillator Selection Status Interrupt Enable */
#define PMC_IER_MOSCRCS (0x1u << 17) /**< \brief (PMC_IER) Main On-Chip RC Status Interrupt Enable */
#define PMC_IER_CFDEV (0x1u << 18) /**< \brief (PMC_IER) Clock Failure Detector Event Interrupt Enable */
/* -------- PMC_IDR : (PMC Offset: 0x0064) Interrupt Disable Register -------- */
#define PMC_IDR_MOSCXTS (0x1u << 0) /**< \brief (PMC_IDR) Main Crystal Oscillator Status Interrupt Disable */
#define PMC_IDR_LOCKA (0x1u << 1) /**< \brief (PMC_IDR) PLLA Lock Interrupt Disable */
#define PMC_IDR_MCKRDY (0x1u << 3) /**< \brief (PMC_IDR) Master Clock Ready Interrupt Disable */
#define PMC_IDR_LOCKU (0x1u << 6) /**< \brief (PMC_IDR) UTMI PLL Lock Interrupt Disable */
#define PMC_IDR_PCKRDY0 (0x1u << 8) /**< \brief (PMC_IDR) Programmable Clock Ready 0 Interrupt Disable */
#define PMC_IDR_PCKRDY1 (0x1u << 9) /**< \brief (PMC_IDR) Programmable Clock Ready 1 Interrupt Disable */
#define PMC_IDR_PCKRDY2 (0x1u << 10) /**< \brief (PMC_IDR) Programmable Clock Ready 2 Interrupt Disable */
#define PMC_IDR_MOSCSELS (0x1u << 16) /**< \brief (PMC_IDR) Main Oscillator Selection Status Interrupt Disable */
#define PMC_IDR_MOSCRCS (0x1u << 17) /**< \brief (PMC_IDR) Main On-Chip RC Status Interrupt Disable */
#define PMC_IDR_CFDEV (0x1u << 18) /**< \brief (PMC_IDR) Clock Failure Detector Event Interrupt Disable */
/* -------- PMC_SR : (PMC Offset: 0x0068) Status Register -------- */
#define PMC_SR_MOSCXTS (0x1u << 0) /**< \brief (PMC_SR) Main XTAL Oscillator Status */
#define PMC_SR_LOCKA (0x1u << 1) /**< \brief (PMC_SR) PLLA Lock Status */
#define PMC_SR_MCKRDY (0x1u << 3) /**< \brief (PMC_SR) Master Clock Status */
#define PMC_SR_LOCKU (0x1u << 6) /**< \brief (PMC_SR) UTMI PLL Lock Status */
#define PMC_SR_OSCSELS (0x1u << 7) /**< \brief (PMC_SR) Slow Clock Oscillator Selection */
#define PMC_SR_PCKRDY0 (0x1u << 8) /**< \brief (PMC_SR) Programmable Clock Ready Status */
#define PMC_SR_PCKRDY1 (0x1u << 9) /**< \brief (PMC_SR) Programmable Clock Ready Status */
#define PMC_SR_PCKRDY2 (0x1u << 10) /**< \brief (PMC_SR) Programmable Clock Ready Status */
#define PMC_SR_MOSCSELS (0x1u << 16) /**< \brief (PMC_SR) Main Oscillator Selection Status */
#define PMC_SR_MOSCRCS (0x1u << 17) /**< \brief (PMC_SR) Main On-Chip RC Oscillator Status */
#define PMC_SR_CFDEV (0x1u << 18) /**< \brief (PMC_SR) Clock Failure Detector Event */
#define PMC_SR_CFDS (0x1u << 19) /**< \brief (PMC_SR) Clock Failure Detector Status */
#define PMC_SR_FOS (0x1u << 20) /**< \brief (PMC_SR) Clock Failure Detector Fault Output Status */
/* -------- PMC_IMR : (PMC Offset: 0x006C) Interrupt Mask Register -------- */
#define PMC_IMR_MOSCXTS (0x1u << 0) /**< \brief (PMC_IMR) Main Crystal Oscillator Status Interrupt Mask */
#define PMC_IMR_LOCKA (0x1u << 1) /**< \brief (PMC_IMR) PLLA Lock Interrupt Mask */
#define PMC_IMR_MCKRDY (0x1u << 3) /**< \brief (PMC_IMR) Master Clock Ready Interrupt Mask */
#define PMC_IMR_LOCKU (0x1u << 6) /**< \brief (PMC_IMR) UTMI PLL Lock Interrupt Mask */
#define PMC_IMR_PCKRDY0 (0x1u << 8) /**< \brief (PMC_IMR) Programmable Clock Ready 0 Interrupt Mask */
#define PMC_IMR_PCKRDY1 (0x1u << 9) /**< \brief (PMC_IMR) Programmable Clock Ready 1 Interrupt Mask */
#define PMC_IMR_PCKRDY2 (0x1u << 10) /**< \brief (PMC_IMR) Programmable Clock Ready 2 Interrupt Mask */
#define PMC_IMR_MOSCSELS (0x1u << 16) /**< \brief (PMC_IMR) Main Oscillator Selection Status Interrupt Mask */
#define PMC_IMR_MOSCRCS (0x1u << 17) /**< \brief (PMC_IMR) Main On-Chip RC Status Interrupt Mask */
#define PMC_IMR_CFDEV (0x1u << 18) /**< \brief (PMC_IMR) Clock Failure Detector Event Interrupt Mask */
/* -------- PMC_FSMR : (PMC Offset: 0x0070) Fast Startup Mode Register -------- */
#define PMC_FSMR_FSTT0 (0x1u << 0) /**< \brief (PMC_FSMR) Fast Startup Input Enable 0 */
#define PMC_FSMR_FSTT1 (0x1u << 1) /**< \brief (PMC_FSMR) Fast Startup Input Enable 1 */
#define PMC_FSMR_FSTT2 (0x1u << 2) /**< \brief (PMC_FSMR) Fast Startup Input Enable 2 */
#define PMC_FSMR_FSTT3 (0x1u << 3) /**< \brief (PMC_FSMR) Fast Startup Input Enable 3 */
#define PMC_FSMR_FSTT4 (0x1u << 4) /**< \brief (PMC_FSMR) Fast Startup Input Enable 4 */
#define PMC_FSMR_FSTT5 (0x1u << 5) /**< \brief (PMC_FSMR) Fast Startup Input Enable 5 */
#define PMC_FSMR_FSTT6 (0x1u << 6) /**< \brief (PMC_FSMR) Fast Startup Input Enable 6 */
#define PMC_FSMR_FSTT7 (0x1u << 7) /**< \brief (PMC_FSMR) Fast Startup Input Enable 7 */
#define PMC_FSMR_FSTT8 (0x1u << 8) /**< \brief (PMC_FSMR) Fast Startup Input Enable 8 */
#define PMC_FSMR_FSTT9 (0x1u << 9) /**< \brief (PMC_FSMR) Fast Startup Input Enable 9 */
#define PMC_FSMR_FSTT10 (0x1u << 10) /**< \brief (PMC_FSMR) Fast Startup Input Enable 10 */
#define PMC_FSMR_FSTT11 (0x1u << 11) /**< \brief (PMC_FSMR) Fast Startup Input Enable 11 */
#define PMC_FSMR_FSTT12 (0x1u << 12) /**< \brief (PMC_FSMR) Fast Startup Input Enable 12 */
#define PMC_FSMR_FSTT13 (0x1u << 13) /**< \brief (PMC_FSMR) Fast Startup Input Enable 13 */
#define PMC_FSMR_FSTT14 (0x1u << 14) /**< \brief (PMC_FSMR) Fast Startup Input Enable 14 */
#define PMC_FSMR_FSTT15 (0x1u << 15) /**< \brief (PMC_FSMR) Fast Startup Input Enable 15 */
#define PMC_FSMR_RTTAL (0x1u << 16) /**< \brief (PMC_FSMR) RTT Alarm Enable */
#define PMC_FSMR_RTCAL (0x1u << 17) /**< \brief (PMC_FSMR) RTC Alarm Enable */
#define PMC_FSMR_USBAL (0x1u << 18) /**< \brief (PMC_FSMR) USB Alarm Enable */
#define PMC_FSMR_LPM (0x1u << 20) /**< \brief (PMC_FSMR) Low Power Mode */
/* -------- PMC_FSPR : (PMC Offset: 0x0074) Fast Startup Polarity Register -------- */
#define PMC_FSPR_FSTP0 (0x1u << 0) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */
#define PMC_FSPR_FSTP1 (0x1u << 1) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */
#define PMC_FSPR_FSTP2 (0x1u << 2) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */
#define PMC_FSPR_FSTP3 (0x1u << 3) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */
#define PMC_FSPR_FSTP4 (0x1u << 4) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */
#define PMC_FSPR_FSTP5 (0x1u << 5) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */
#define PMC_FSPR_FSTP6 (0x1u << 6) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */
#define PMC_FSPR_FSTP7 (0x1u << 7) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */
#define PMC_FSPR_FSTP8 (0x1u << 8) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */
#define PMC_FSPR_FSTP9 (0x1u << 9) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */
#define PMC_FSPR_FSTP10 (0x1u << 10) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */
#define PMC_FSPR_FSTP11 (0x1u << 11) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */
#define PMC_FSPR_FSTP12 (0x1u << 12) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */
#define PMC_FSPR_FSTP13 (0x1u << 13) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */
#define PMC_FSPR_FSTP14 (0x1u << 14) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */
#define PMC_FSPR_FSTP15 (0x1u << 15) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */
/* -------- PMC_FOCR : (PMC Offset: 0x0078) Fault Output Clear Register -------- */
#define PMC_FOCR_FOCLR (0x1u << 0) /**< \brief (PMC_FOCR) Fault Output Clear */
/* -------- PMC_WPMR : (PMC Offset: 0x00E4) Write Protect Mode Register -------- */
#define PMC_WPMR_WPEN (0x1u << 0) /**< \brief (PMC_WPMR) Write Protect Enable */
#define PMC_WPMR_WPKEY_Pos 8
#define PMC_WPMR_WPKEY_Msk (0xffffffu << PMC_WPMR_WPKEY_Pos) /**< \brief (PMC_WPMR) Write Protect KEY */
#define PMC_WPMR_WPKEY(value) ((PMC_WPMR_WPKEY_Msk & ((value) << PMC_WPMR_WPKEY_Pos)))
/* -------- PMC_WPSR : (PMC Offset: 0x00E8) Write Protect Status Register -------- */
#define PMC_WPSR_WPVS (0x1u << 0) /**< \brief (PMC_WPSR) Write Protect Violation Status */
#define PMC_WPSR_WPVSRC_Pos 8
#define PMC_WPSR_WPVSRC_Msk (0xffffu << PMC_WPSR_WPVSRC_Pos) /**< \brief (PMC_WPSR) Write Protect Violation Source */
/* -------- PMC_PCER1 : (PMC Offset: 0x0100) Peripheral Clock Enable Register 1 -------- */
#define PMC_PCER1_PID32 (0x1u << 0) /**< \brief (PMC_PCER1) Peripheral Clock 32 Enable */
#define PMC_PCER1_PID33 (0x1u << 1) /**< \brief (PMC_PCER1) Peripheral Clock 33 Enable */
#define PMC_PCER1_PID34 (0x1u << 2) /**< \brief (PMC_PCER1) Peripheral Clock 34 Enable */
#define PMC_PCER1_PID35 (0x1u << 3) /**< \brief (PMC_PCER1) Peripheral Clock 35 Enable */
#define PMC_PCER1_PID36 (0x1u << 4) /**< \brief (PMC_PCER1) Peripheral Clock 36 Enable */
#define PMC_PCER1_PID37 (0x1u << 5) /**< \brief (PMC_PCER1) Peripheral Clock 37 Enable */
#define PMC_PCER1_PID38 (0x1u << 6) /**< \brief (PMC_PCER1) Peripheral Clock 38 Enable */
#define PMC_PCER1_PID39 (0x1u << 7) /**< \brief (PMC_PCER1) Peripheral Clock 39 Enable */
#define PMC_PCER1_PID40 (0x1u << 8) /**< \brief (PMC_PCER1) Peripheral Clock 40 Enable */
#define PMC_PCER1_PID41 (0x1u << 9) /**< \brief (PMC_PCER1) Peripheral Clock 41 Enable */
#define PMC_PCER1_PID42 (0x1u << 10) /**< \brief (PMC_PCER1) Peripheral Clock 42 Enable */
#define PMC_PCER1_PID43 (0x1u << 11) /**< \brief (PMC_PCER1) Peripheral Clock 43 Enable */
#define PMC_PCER1_PID44 (0x1u << 12) /**< \brief (PMC_PCER1) Peripheral Clock 44 Enable */
/* -------- PMC_PCDR1 : (PMC Offset: 0x0104) Peripheral Clock Disable Register 1 -------- */
#define PMC_PCDR1_PID32 (0x1u << 0) /**< \brief (PMC_PCDR1) Peripheral Clock 32 Disable */
#define PMC_PCDR1_PID33 (0x1u << 1) /**< \brief (PMC_PCDR1) Peripheral Clock 33 Disable */
#define PMC_PCDR1_PID34 (0x1u << 2) /**< \brief (PMC_PCDR1) Peripheral Clock 34 Disable */
#define PMC_PCDR1_PID35 (0x1u << 3) /**< \brief (PMC_PCDR1) Peripheral Clock 35 Disable */
#define PMC_PCDR1_PID36 (0x1u << 4) /**< \brief (PMC_PCDR1) Peripheral Clock 36 Disable */
#define PMC_PCDR1_PID37 (0x1u << 5) /**< \brief (PMC_PCDR1) Peripheral Clock 37 Disable */
#define PMC_PCDR1_PID38 (0x1u << 6) /**< \brief (PMC_PCDR1) Peripheral Clock 38 Disable */
#define PMC_PCDR1_PID39 (0x1u << 7) /**< \brief (PMC_PCDR1) Peripheral Clock 39 Disable */
#define PMC_PCDR1_PID40 (0x1u << 8) /**< \brief (PMC_PCDR1) Peripheral Clock 40 Disable */
#define PMC_PCDR1_PID41 (0x1u << 9) /**< \brief (PMC_PCDR1) Peripheral Clock 41 Disable */
#define PMC_PCDR1_PID42 (0x1u << 10) /**< \brief (PMC_PCDR1) Peripheral Clock 42 Disable */
#define PMC_PCDR1_PID43 (0x1u << 11) /**< \brief (PMC_PCDR1) Peripheral Clock 43 Disable */
#define PMC_PCDR1_PID44 (0x1u << 12) /**< \brief (PMC_PCDR1) Peripheral Clock 44 Disable */
/* -------- PMC_PCSR1 : (PMC Offset: 0x0108) Peripheral Clock Status Register 1 -------- */
#define PMC_PCSR1_PID32 (0x1u << 0) /**< \brief (PMC_PCSR1) Peripheral Clock 32 Status */
#define PMC_PCSR1_PID33 (0x1u << 1) /**< \brief (PMC_PCSR1) Peripheral Clock 33 Status */
#define PMC_PCSR1_PID34 (0x1u << 2) /**< \brief (PMC_PCSR1) Peripheral Clock 34 Status */
#define PMC_PCSR1_PID35 (0x1u << 3) /**< \brief (PMC_PCSR1) Peripheral Clock 35 Status */
#define PMC_PCSR1_PID36 (0x1u << 4) /**< \brief (PMC_PCSR1) Peripheral Clock 36 Status */
#define PMC_PCSR1_PID37 (0x1u << 5) /**< \brief (PMC_PCSR1) Peripheral Clock 37 Status */
#define PMC_PCSR1_PID38 (0x1u << 6) /**< \brief (PMC_PCSR1) Peripheral Clock 38 Status */
#define PMC_PCSR1_PID39 (0x1u << 7) /**< \brief (PMC_PCSR1) Peripheral Clock 39 Status */
#define PMC_PCSR1_PID40 (0x1u << 8) /**< \brief (PMC_PCSR1) Peripheral Clock 40 Status */
#define PMC_PCSR1_PID41 (0x1u << 9) /**< \brief (PMC_PCSR1) Peripheral Clock 41 Status */
#define PMC_PCSR1_PID42 (0x1u << 10) /**< \brief (PMC_PCSR1) Peripheral Clock 42 Status */
#define PMC_PCSR1_PID43 (0x1u << 11) /**< \brief (PMC_PCSR1) Peripheral Clock 43 Status */
#define PMC_PCSR1_PID44 (0x1u << 12) /**< \brief (PMC_PCSR1) Peripheral Clock 44 Status */
/* -------- PMC_PCR : (PMC Offset: 0x010C) Peripheral Control Register -------- */
#define PMC_PCR_PID_Pos 0
#define PMC_PCR_PID_Msk (0x3fu << PMC_PCR_PID_Pos) /**< \brief (PMC_PCR) Peripheral ID */
#define PMC_PCR_PID(value) ((PMC_PCR_PID_Msk & ((value) << PMC_PCR_PID_Pos)))
#define PMC_PCR_CMD (0x1u << 12) /**< \brief (PMC_PCR) Command */
#define PMC_PCR_DIV_Pos 16
#define PMC_PCR_DIV_Msk (0x3u << PMC_PCR_DIV_Pos) /**< \brief (PMC_PCR) Divisor Value */
#define PMC_PCR_DIV_PERIPH_DIV_MCK (0x0u << 16) /**< \brief (PMC_PCR) Peripheral clock is MCK */
#define PMC_PCR_DIV_PERIPH_DIV2_MCK (0x1u << 16) /**< \brief (PMC_PCR) Peripheral clock is MCK/2 */
#define PMC_PCR_DIV_PERIPH_DIV4_MCK (0x2u << 16) /**< \brief (PMC_PCR) Peripheral clock is MCK/4 */
#define PMC_PCR_EN (0x1u << 28) /**< \brief (PMC_PCR) Enable */
/*@}*/
#endif /* _SAM3XA_PMC_COMPONENT_ */

View File

@@ -0,0 +1,667 @@
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2012, Atmel Corporation
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following condition is met:
*
* - Redistributions of source code must retain the above copyright notice,
* this list of conditions and the disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ----------------------------------------------------------------------------
*/
#ifndef _SAM3XA_PWM_COMPONENT_
#define _SAM3XA_PWM_COMPONENT_
/* ============================================================================= */
/** SOFTWARE API DEFINITION FOR Pulse Width Modulation Controller */
/* ============================================================================= */
/** \addtogroup SAM3XA_PWM Pulse Width Modulation Controller */
/*@{*/
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
/** \brief PwmCh_num hardware registers */
typedef struct {
RwReg PWM_CMR; /**< \brief (PwmCh_num Offset: 0x0) PWM Channel Mode Register */
RwReg PWM_CDTY; /**< \brief (PwmCh_num Offset: 0x4) PWM Channel Duty Cycle Register */
RwReg PWM_CDTYUPD; /**< \brief (PwmCh_num Offset: 0x8) PWM Channel Duty Cycle Update Register */
RwReg PWM_CPRD; /**< \brief (PwmCh_num Offset: 0xC) PWM Channel Period Register */
RwReg PWM_CPRDUPD; /**< \brief (PwmCh_num Offset: 0x10) PWM Channel Period Update Register */
RwReg PWM_CCNT; /**< \brief (PwmCh_num Offset: 0x14) PWM Channel Counter Register */
RwReg PWM_DT; /**< \brief (PwmCh_num Offset: 0x18) PWM Channel Dead Time Register */
RwReg PWM_DTUPD; /**< \brief (PwmCh_num Offset: 0x1C) PWM Channel Dead Time Update Register */
} PwmCh_num;
/** \brief PwmCmp hardware registers */
typedef struct {
RwReg PWM_CMPV; /**< \brief (PwmCmp Offset: 0x0) PWM Comparison 0 Value Register */
RwReg PWM_CMPVUPD; /**< \brief (PwmCmp Offset: 0x4) PWM Comparison 0 Value Update Register */
RwReg PWM_CMPM; /**< \brief (PwmCmp Offset: 0x8) PWM Comparison 0 Mode Register */
RwReg PWM_CMPMUPD; /**< \brief (PwmCmp Offset: 0xC) PWM Comparison 0 Mode Update Register */
} PwmCmp;
/** \brief Pwm hardware registers */
#define PWMCMP_NUMBER 8
#define PWMCH_NUM_NUMBER 8
typedef struct {
RwReg PWM_CLK; /**< \brief (Pwm Offset: 0x00) PWM Clock Register */
WoReg PWM_ENA; /**< \brief (Pwm Offset: 0x04) PWM Enable Register */
WoReg PWM_DIS; /**< \brief (Pwm Offset: 0x08) PWM Disable Register */
RoReg PWM_SR; /**< \brief (Pwm Offset: 0x0C) PWM Status Register */
WoReg PWM_IER1; /**< \brief (Pwm Offset: 0x10) PWM Interrupt Enable Register 1 */
WoReg PWM_IDR1; /**< \brief (Pwm Offset: 0x14) PWM Interrupt Disable Register 1 */
RoReg PWM_IMR1; /**< \brief (Pwm Offset: 0x18) PWM Interrupt Mask Register 1 */
RoReg PWM_ISR1; /**< \brief (Pwm Offset: 0x1C) PWM Interrupt Status Register 1 */
RwReg PWM_SCM; /**< \brief (Pwm Offset: 0x20) PWM Sync Channels Mode Register */
RoReg Reserved1[1];
RwReg PWM_SCUC; /**< \brief (Pwm Offset: 0x28) PWM Sync Channels Update Control Register */
RwReg PWM_SCUP; /**< \brief (Pwm Offset: 0x2C) PWM Sync Channels Update Period Register */
WoReg PWM_SCUPUPD; /**< \brief (Pwm Offset: 0x30) PWM Sync Channels Update Period Update Register */
WoReg PWM_IER2; /**< \brief (Pwm Offset: 0x34) PWM Interrupt Enable Register 2 */
WoReg PWM_IDR2; /**< \brief (Pwm Offset: 0x38) PWM Interrupt Disable Register 2 */
RoReg PWM_IMR2; /**< \brief (Pwm Offset: 0x3C) PWM Interrupt Mask Register 2 */
RoReg PWM_ISR2; /**< \brief (Pwm Offset: 0x40) PWM Interrupt Status Register 2 */
RwReg PWM_OOV; /**< \brief (Pwm Offset: 0x44) PWM Output Override Value Register */
RwReg PWM_OS; /**< \brief (Pwm Offset: 0x48) PWM Output Selection Register */
WoReg PWM_OSS; /**< \brief (Pwm Offset: 0x4C) PWM Output Selection Set Register */
WoReg PWM_OSC; /**< \brief (Pwm Offset: 0x50) PWM Output Selection Clear Register */
WoReg PWM_OSSUPD; /**< \brief (Pwm Offset: 0x54) PWM Output Selection Set Update Register */
WoReg PWM_OSCUPD; /**< \brief (Pwm Offset: 0x58) PWM Output Selection Clear Update Register */
RwReg PWM_FMR; /**< \brief (Pwm Offset: 0x5C) PWM Fault Mode Register */
RoReg PWM_FSR; /**< \brief (Pwm Offset: 0x60) PWM Fault Status Register */
WoReg PWM_FCR; /**< \brief (Pwm Offset: 0x64) PWM Fault Clear Register */
RwReg PWM_FPV; /**< \brief (Pwm Offset: 0x68) PWM Fault Protection Value Register */
RwReg PWM_FPE1; /**< \brief (Pwm Offset: 0x6C) PWM Fault Protection Enable Register 1 */
RwReg PWM_FPE2; /**< \brief (Pwm Offset: 0x70) PWM Fault Protection Enable Register 2 */
RoReg Reserved2[2];
RwReg PWM_ELMR[2]; /**< \brief (Pwm Offset: 0x7C) PWM Event Line 0 Mode Register */
RoReg Reserved3[11];
RwReg PWM_SMMR; /**< \brief (Pwm Offset: 0xB0) PWM Stepper Motor Mode Register */
RoReg Reserved4[12];
WoReg PWM_WPCR; /**< \brief (Pwm Offset: 0xE4) PWM Write Protect Control Register */
RoReg PWM_WPSR; /**< \brief (Pwm Offset: 0xE8) PWM Write Protect Status Register */
RoReg Reserved5[7];
RwReg PWM_TPR; /**< \brief (Pwm Offset: 0x108) Transmit Pointer Register */
RwReg PWM_TCR; /**< \brief (Pwm Offset: 0x10C) Transmit Counter Register */
RoReg Reserved6[2];
RwReg PWM_TNPR; /**< \brief (Pwm Offset: 0x118) Transmit Next Pointer Register */
RwReg PWM_TNCR; /**< \brief (Pwm Offset: 0x11C) Transmit Next Counter Register */
WoReg PWM_PTCR; /**< \brief (Pwm Offset: 0x120) Transfer Control Register */
RoReg PWM_PTSR; /**< \brief (Pwm Offset: 0x124) Transfer Status Register */
RoReg Reserved7[2];
PwmCmp PWM_CMP[PWMCMP_NUMBER]; /**< \brief (Pwm Offset: 0x130) 0 .. 7 */
RoReg Reserved8[20];
PwmCh_num PWM_CH_NUM[PWMCH_NUM_NUMBER]; /**< \brief (Pwm Offset: 0x200) ch_num = 0 .. 7 */
} Pwm;
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
/* -------- PWM_CLK : (PWM Offset: 0x00) PWM Clock Register -------- */
#define PWM_CLK_DIVA_Pos 0
#define PWM_CLK_DIVA_Msk (0xffu << PWM_CLK_DIVA_Pos) /**< \brief (PWM_CLK) CLKA, CLKB Divide Factor */
#define PWM_CLK_DIVA(value) ((PWM_CLK_DIVA_Msk & ((value) << PWM_CLK_DIVA_Pos)))
#define PWM_CLK_PREA_Pos 8
#define PWM_CLK_PREA_Msk (0xfu << PWM_CLK_PREA_Pos) /**< \brief (PWM_CLK) CLKA, CLKB Source Clock Selection */
#define PWM_CLK_PREA(value) ((PWM_CLK_PREA_Msk & ((value) << PWM_CLK_PREA_Pos)))
#define PWM_CLK_DIVB_Pos 16
#define PWM_CLK_DIVB_Msk (0xffu << PWM_CLK_DIVB_Pos) /**< \brief (PWM_CLK) CLKA, CLKB Divide Factor */
#define PWM_CLK_DIVB(value) ((PWM_CLK_DIVB_Msk & ((value) << PWM_CLK_DIVB_Pos)))
#define PWM_CLK_PREB_Pos 24
#define PWM_CLK_PREB_Msk (0xfu << PWM_CLK_PREB_Pos) /**< \brief (PWM_CLK) CLKA, CLKB Source Clock Selection */
#define PWM_CLK_PREB(value) ((PWM_CLK_PREB_Msk & ((value) << PWM_CLK_PREB_Pos)))
/* -------- PWM_ENA : (PWM Offset: 0x04) PWM Enable Register -------- */
#define PWM_ENA_CHID0 (0x1u << 0) /**< \brief (PWM_ENA) Channel ID */
#define PWM_ENA_CHID1 (0x1u << 1) /**< \brief (PWM_ENA) Channel ID */
#define PWM_ENA_CHID2 (0x1u << 2) /**< \brief (PWM_ENA) Channel ID */
#define PWM_ENA_CHID3 (0x1u << 3) /**< \brief (PWM_ENA) Channel ID */
#define PWM_ENA_CHID4 (0x1u << 4) /**< \brief (PWM_ENA) Channel ID */
#define PWM_ENA_CHID5 (0x1u << 5) /**< \brief (PWM_ENA) Channel ID */
#define PWM_ENA_CHID6 (0x1u << 6) /**< \brief (PWM_ENA) Channel ID */
#define PWM_ENA_CHID7 (0x1u << 7) /**< \brief (PWM_ENA) Channel ID */
/* -------- PWM_DIS : (PWM Offset: 0x08) PWM Disable Register -------- */
#define PWM_DIS_CHID0 (0x1u << 0) /**< \brief (PWM_DIS) Channel ID */
#define PWM_DIS_CHID1 (0x1u << 1) /**< \brief (PWM_DIS) Channel ID */
#define PWM_DIS_CHID2 (0x1u << 2) /**< \brief (PWM_DIS) Channel ID */
#define PWM_DIS_CHID3 (0x1u << 3) /**< \brief (PWM_DIS) Channel ID */
#define PWM_DIS_CHID4 (0x1u << 4) /**< \brief (PWM_DIS) Channel ID */
#define PWM_DIS_CHID5 (0x1u << 5) /**< \brief (PWM_DIS) Channel ID */
#define PWM_DIS_CHID6 (0x1u << 6) /**< \brief (PWM_DIS) Channel ID */
#define PWM_DIS_CHID7 (0x1u << 7) /**< \brief (PWM_DIS) Channel ID */
/* -------- PWM_SR : (PWM Offset: 0x0C) PWM Status Register -------- */
#define PWM_SR_CHID0 (0x1u << 0) /**< \brief (PWM_SR) Channel ID */
#define PWM_SR_CHID1 (0x1u << 1) /**< \brief (PWM_SR) Channel ID */
#define PWM_SR_CHID2 (0x1u << 2) /**< \brief (PWM_SR) Channel ID */
#define PWM_SR_CHID3 (0x1u << 3) /**< \brief (PWM_SR) Channel ID */
#define PWM_SR_CHID4 (0x1u << 4) /**< \brief (PWM_SR) Channel ID */
#define PWM_SR_CHID5 (0x1u << 5) /**< \brief (PWM_SR) Channel ID */
#define PWM_SR_CHID6 (0x1u << 6) /**< \brief (PWM_SR) Channel ID */
#define PWM_SR_CHID7 (0x1u << 7) /**< \brief (PWM_SR) Channel ID */
/* -------- PWM_IER1 : (PWM Offset: 0x10) PWM Interrupt Enable Register 1 -------- */
#define PWM_IER1_CHID0 (0x1u << 0) /**< \brief (PWM_IER1) Counter Event on Channel 0 Interrupt Enable */
#define PWM_IER1_CHID1 (0x1u << 1) /**< \brief (PWM_IER1) Counter Event on Channel 1 Interrupt Enable */
#define PWM_IER1_CHID2 (0x1u << 2) /**< \brief (PWM_IER1) Counter Event on Channel 2 Interrupt Enable */
#define PWM_IER1_CHID3 (0x1u << 3) /**< \brief (PWM_IER1) Counter Event on Channel 3 Interrupt Enable */
#define PWM_IER1_CHID4 (0x1u << 4) /**< \brief (PWM_IER1) Counter Event on Channel 4 Interrupt Enable */
#define PWM_IER1_CHID5 (0x1u << 5) /**< \brief (PWM_IER1) Counter Event on Channel 5 Interrupt Enable */
#define PWM_IER1_CHID6 (0x1u << 6) /**< \brief (PWM_IER1) Counter Event on Channel 6 Interrupt Enable */
#define PWM_IER1_CHID7 (0x1u << 7) /**< \brief (PWM_IER1) Counter Event on Channel 7 Interrupt Enable */
#define PWM_IER1_FCHID0 (0x1u << 16) /**< \brief (PWM_IER1) Fault Protection Trigger on Channel 0 Interrupt Enable */
#define PWM_IER1_FCHID1 (0x1u << 17) /**< \brief (PWM_IER1) Fault Protection Trigger on Channel 1 Interrupt Enable */
#define PWM_IER1_FCHID2 (0x1u << 18) /**< \brief (PWM_IER1) Fault Protection Trigger on Channel 2 Interrupt Enable */
#define PWM_IER1_FCHID3 (0x1u << 19) /**< \brief (PWM_IER1) Fault Protection Trigger on Channel 3 Interrupt Enable */
#define PWM_IER1_FCHID4 (0x1u << 20) /**< \brief (PWM_IER1) Fault Protection Trigger on Channel 4 Interrupt Enable */
#define PWM_IER1_FCHID5 (0x1u << 21) /**< \brief (PWM_IER1) Fault Protection Trigger on Channel 5 Interrupt Enable */
#define PWM_IER1_FCHID6 (0x1u << 22) /**< \brief (PWM_IER1) Fault Protection Trigger on Channel 6 Interrupt Enable */
#define PWM_IER1_FCHID7 (0x1u << 23) /**< \brief (PWM_IER1) Fault Protection Trigger on Channel 7 Interrupt Enable */
/* -------- PWM_IDR1 : (PWM Offset: 0x14) PWM Interrupt Disable Register 1 -------- */
#define PWM_IDR1_CHID0 (0x1u << 0) /**< \brief (PWM_IDR1) Counter Event on Channel 0 Interrupt Disable */
#define PWM_IDR1_CHID1 (0x1u << 1) /**< \brief (PWM_IDR1) Counter Event on Channel 1 Interrupt Disable */
#define PWM_IDR1_CHID2 (0x1u << 2) /**< \brief (PWM_IDR1) Counter Event on Channel 2 Interrupt Disable */
#define PWM_IDR1_CHID3 (0x1u << 3) /**< \brief (PWM_IDR1) Counter Event on Channel 3 Interrupt Disable */
#define PWM_IDR1_CHID4 (0x1u << 4) /**< \brief (PWM_IDR1) Counter Event on Channel 4 Interrupt Disable */
#define PWM_IDR1_CHID5 (0x1u << 5) /**< \brief (PWM_IDR1) Counter Event on Channel 5 Interrupt Disable */
#define PWM_IDR1_CHID6 (0x1u << 6) /**< \brief (PWM_IDR1) Counter Event on Channel 6 Interrupt Disable */
#define PWM_IDR1_CHID7 (0x1u << 7) /**< \brief (PWM_IDR1) Counter Event on Channel 7 Interrupt Disable */
#define PWM_IDR1_FCHID0 (0x1u << 16) /**< \brief (PWM_IDR1) Fault Protection Trigger on Channel 0 Interrupt Disable */
#define PWM_IDR1_FCHID1 (0x1u << 17) /**< \brief (PWM_IDR1) Fault Protection Trigger on Channel 1 Interrupt Disable */
#define PWM_IDR1_FCHID2 (0x1u << 18) /**< \brief (PWM_IDR1) Fault Protection Trigger on Channel 2 Interrupt Disable */
#define PWM_IDR1_FCHID3 (0x1u << 19) /**< \brief (PWM_IDR1) Fault Protection Trigger on Channel 3 Interrupt Disable */
#define PWM_IDR1_FCHID4 (0x1u << 20) /**< \brief (PWM_IDR1) Fault Protection Trigger on Channel 4 Interrupt Disable */
#define PWM_IDR1_FCHID5 (0x1u << 21) /**< \brief (PWM_IDR1) Fault Protection Trigger on Channel 5 Interrupt Disable */
#define PWM_IDR1_FCHID6 (0x1u << 22) /**< \brief (PWM_IDR1) Fault Protection Trigger on Channel 6 Interrupt Disable */
#define PWM_IDR1_FCHID7 (0x1u << 23) /**< \brief (PWM_IDR1) Fault Protection Trigger on Channel 7 Interrupt Disable */
/* -------- PWM_IMR1 : (PWM Offset: 0x18) PWM Interrupt Mask Register 1 -------- */
#define PWM_IMR1_CHID0 (0x1u << 0) /**< \brief (PWM_IMR1) Counter Event on Channel 0 Interrupt Mask */
#define PWM_IMR1_CHID1 (0x1u << 1) /**< \brief (PWM_IMR1) Counter Event on Channel 1 Interrupt Mask */
#define PWM_IMR1_CHID2 (0x1u << 2) /**< \brief (PWM_IMR1) Counter Event on Channel 2 Interrupt Mask */
#define PWM_IMR1_CHID3 (0x1u << 3) /**< \brief (PWM_IMR1) Counter Event on Channel 3 Interrupt Mask */
#define PWM_IMR1_CHID4 (0x1u << 4) /**< \brief (PWM_IMR1) Counter Event on Channel 4 Interrupt Mask */
#define PWM_IMR1_CHID5 (0x1u << 5) /**< \brief (PWM_IMR1) Counter Event on Channel 5 Interrupt Mask */
#define PWM_IMR1_CHID6 (0x1u << 6) /**< \brief (PWM_IMR1) Counter Event on Channel 6 Interrupt Mask */
#define PWM_IMR1_CHID7 (0x1u << 7) /**< \brief (PWM_IMR1) Counter Event on Channel 7 Interrupt Mask */
#define PWM_IMR1_FCHID0 (0x1u << 16) /**< \brief (PWM_IMR1) Fault Protection Trigger on Channel 0 Interrupt Mask */
#define PWM_IMR1_FCHID1 (0x1u << 17) /**< \brief (PWM_IMR1) Fault Protection Trigger on Channel 1 Interrupt Mask */
#define PWM_IMR1_FCHID2 (0x1u << 18) /**< \brief (PWM_IMR1) Fault Protection Trigger on Channel 2 Interrupt Mask */
#define PWM_IMR1_FCHID3 (0x1u << 19) /**< \brief (PWM_IMR1) Fault Protection Trigger on Channel 3 Interrupt Mask */
#define PWM_IMR1_FCHID4 (0x1u << 20) /**< \brief (PWM_IMR1) Fault Protection Trigger on Channel 4 Interrupt Mask */
#define PWM_IMR1_FCHID5 (0x1u << 21) /**< \brief (PWM_IMR1) Fault Protection Trigger on Channel 5 Interrupt Mask */
#define PWM_IMR1_FCHID6 (0x1u << 22) /**< \brief (PWM_IMR1) Fault Protection Trigger on Channel 6 Interrupt Mask */
#define PWM_IMR1_FCHID7 (0x1u << 23) /**< \brief (PWM_IMR1) Fault Protection Trigger on Channel 7 Interrupt Mask */
/* -------- PWM_ISR1 : (PWM Offset: 0x1C) PWM Interrupt Status Register 1 -------- */
#define PWM_ISR1_CHID0 (0x1u << 0) /**< \brief (PWM_ISR1) Counter Event on Channel 0 */
#define PWM_ISR1_CHID1 (0x1u << 1) /**< \brief (PWM_ISR1) Counter Event on Channel 1 */
#define PWM_ISR1_CHID2 (0x1u << 2) /**< \brief (PWM_ISR1) Counter Event on Channel 2 */
#define PWM_ISR1_CHID3 (0x1u << 3) /**< \brief (PWM_ISR1) Counter Event on Channel 3 */
#define PWM_ISR1_CHID4 (0x1u << 4) /**< \brief (PWM_ISR1) Counter Event on Channel 4 */
#define PWM_ISR1_CHID5 (0x1u << 5) /**< \brief (PWM_ISR1) Counter Event on Channel 5 */
#define PWM_ISR1_CHID6 (0x1u << 6) /**< \brief (PWM_ISR1) Counter Event on Channel 6 */
#define PWM_ISR1_CHID7 (0x1u << 7) /**< \brief (PWM_ISR1) Counter Event on Channel 7 */
#define PWM_ISR1_FCHID0 (0x1u << 16) /**< \brief (PWM_ISR1) Fault Protection Trigger on Channel 0 */
#define PWM_ISR1_FCHID1 (0x1u << 17) /**< \brief (PWM_ISR1) Fault Protection Trigger on Channel 1 */
#define PWM_ISR1_FCHID2 (0x1u << 18) /**< \brief (PWM_ISR1) Fault Protection Trigger on Channel 2 */
#define PWM_ISR1_FCHID3 (0x1u << 19) /**< \brief (PWM_ISR1) Fault Protection Trigger on Channel 3 */
#define PWM_ISR1_FCHID4 (0x1u << 20) /**< \brief (PWM_ISR1) Fault Protection Trigger on Channel 4 */
#define PWM_ISR1_FCHID5 (0x1u << 21) /**< \brief (PWM_ISR1) Fault Protection Trigger on Channel 5 */
#define PWM_ISR1_FCHID6 (0x1u << 22) /**< \brief (PWM_ISR1) Fault Protection Trigger on Channel 6 */
#define PWM_ISR1_FCHID7 (0x1u << 23) /**< \brief (PWM_ISR1) Fault Protection Trigger on Channel 7 */
/* -------- PWM_SCM : (PWM Offset: 0x20) PWM Sync Channels Mode Register -------- */
#define PWM_SCM_SYNC0 (0x1u << 0) /**< \brief (PWM_SCM) Synchronous Channel 0 */
#define PWM_SCM_SYNC1 (0x1u << 1) /**< \brief (PWM_SCM) Synchronous Channel 1 */
#define PWM_SCM_SYNC2 (0x1u << 2) /**< \brief (PWM_SCM) Synchronous Channel 2 */
#define PWM_SCM_SYNC3 (0x1u << 3) /**< \brief (PWM_SCM) Synchronous Channel 3 */
#define PWM_SCM_SYNC4 (0x1u << 4) /**< \brief (PWM_SCM) Synchronous Channel 4 */
#define PWM_SCM_SYNC5 (0x1u << 5) /**< \brief (PWM_SCM) Synchronous Channel 5 */
#define PWM_SCM_SYNC6 (0x1u << 6) /**< \brief (PWM_SCM) Synchronous Channel 6 */
#define PWM_SCM_SYNC7 (0x1u << 7) /**< \brief (PWM_SCM) Synchronous Channel 7 */
#define PWM_SCM_UPDM_Pos 16
#define PWM_SCM_UPDM_Msk (0x3u << PWM_SCM_UPDM_Pos) /**< \brief (PWM_SCM) Synchronous Channels Update Mode */
#define PWM_SCM_UPDM_MODE0 (0x0u << 16) /**< \brief (PWM_SCM) Manual write of double buffer registers and manual update of synchronous channels */
#define PWM_SCM_UPDM_MODE1 (0x1u << 16) /**< \brief (PWM_SCM) Manual write of double buffer registers and automatic update of synchronous channels */
#define PWM_SCM_UPDM_MODE2 (0x2u << 16) /**< \brief (PWM_SCM) Automatic write of duty-cycle update registers by the PDC and automatic update of synchronous channels */
#define PWM_SCM_PTRM (0x1u << 20) /**< \brief (PWM_SCM) PDC Transfer Request Mode */
#define PWM_SCM_PTRCS_Pos 21
#define PWM_SCM_PTRCS_Msk (0x7u << PWM_SCM_PTRCS_Pos) /**< \brief (PWM_SCM) PDC Transfer Request Comparison Selection */
#define PWM_SCM_PTRCS(value) ((PWM_SCM_PTRCS_Msk & ((value) << PWM_SCM_PTRCS_Pos)))
/* -------- PWM_SCUC : (PWM Offset: 0x28) PWM Sync Channels Update Control Register -------- */
#define PWM_SCUC_UPDULOCK (0x1u << 0) /**< \brief (PWM_SCUC) Synchronous Channels Update Unlock */
/* -------- PWM_SCUP : (PWM Offset: 0x2C) PWM Sync Channels Update Period Register -------- */
#define PWM_SCUP_UPR_Pos 0
#define PWM_SCUP_UPR_Msk (0xfu << PWM_SCUP_UPR_Pos) /**< \brief (PWM_SCUP) Update Period */
#define PWM_SCUP_UPR(value) ((PWM_SCUP_UPR_Msk & ((value) << PWM_SCUP_UPR_Pos)))
#define PWM_SCUP_UPRCNT_Pos 4
#define PWM_SCUP_UPRCNT_Msk (0xfu << PWM_SCUP_UPRCNT_Pos) /**< \brief (PWM_SCUP) Update Period Counter */
#define PWM_SCUP_UPRCNT(value) ((PWM_SCUP_UPRCNT_Msk & ((value) << PWM_SCUP_UPRCNT_Pos)))
/* -------- PWM_SCUPUPD : (PWM Offset: 0x30) PWM Sync Channels Update Period Update Register -------- */
#define PWM_SCUPUPD_UPRUPD_Pos 0
#define PWM_SCUPUPD_UPRUPD_Msk (0xfu << PWM_SCUPUPD_UPRUPD_Pos) /**< \brief (PWM_SCUPUPD) Update Period Update */
#define PWM_SCUPUPD_UPRUPD(value) ((PWM_SCUPUPD_UPRUPD_Msk & ((value) << PWM_SCUPUPD_UPRUPD_Pos)))
/* -------- PWM_IER2 : (PWM Offset: 0x34) PWM Interrupt Enable Register 2 -------- */
#define PWM_IER2_WRDY (0x1u << 0) /**< \brief (PWM_IER2) Write Ready for Synchronous Channels Update Interrupt Enable */
#define PWM_IER2_ENDTX (0x1u << 1) /**< \brief (PWM_IER2) PDC End of TX Buffer Interrupt Enable */
#define PWM_IER2_TXBUFE (0x1u << 2) /**< \brief (PWM_IER2) PDC TX Buffer Empty Interrupt Enable */
#define PWM_IER2_UNRE (0x1u << 3) /**< \brief (PWM_IER2) Synchronous Channels Update Underrun Error Interrupt Enable */
#define PWM_IER2_CMPM0 (0x1u << 8) /**< \brief (PWM_IER2) Comparison 0 Match Interrupt Enable */
#define PWM_IER2_CMPM1 (0x1u << 9) /**< \brief (PWM_IER2) Comparison 1 Match Interrupt Enable */
#define PWM_IER2_CMPM2 (0x1u << 10) /**< \brief (PWM_IER2) Comparison 2 Match Interrupt Enable */
#define PWM_IER2_CMPM3 (0x1u << 11) /**< \brief (PWM_IER2) Comparison 3 Match Interrupt Enable */
#define PWM_IER2_CMPM4 (0x1u << 12) /**< \brief (PWM_IER2) Comparison 4 Match Interrupt Enable */
#define PWM_IER2_CMPM5 (0x1u << 13) /**< \brief (PWM_IER2) Comparison 5 Match Interrupt Enable */
#define PWM_IER2_CMPM6 (0x1u << 14) /**< \brief (PWM_IER2) Comparison 6 Match Interrupt Enable */
#define PWM_IER2_CMPM7 (0x1u << 15) /**< \brief (PWM_IER2) Comparison 7 Match Interrupt Enable */
#define PWM_IER2_CMPU0 (0x1u << 16) /**< \brief (PWM_IER2) Comparison 0 Update Interrupt Enable */
#define PWM_IER2_CMPU1 (0x1u << 17) /**< \brief (PWM_IER2) Comparison 1 Update Interrupt Enable */
#define PWM_IER2_CMPU2 (0x1u << 18) /**< \brief (PWM_IER2) Comparison 2 Update Interrupt Enable */
#define PWM_IER2_CMPU3 (0x1u << 19) /**< \brief (PWM_IER2) Comparison 3 Update Interrupt Enable */
#define PWM_IER2_CMPU4 (0x1u << 20) /**< \brief (PWM_IER2) Comparison 4 Update Interrupt Enable */
#define PWM_IER2_CMPU5 (0x1u << 21) /**< \brief (PWM_IER2) Comparison 5 Update Interrupt Enable */
#define PWM_IER2_CMPU6 (0x1u << 22) /**< \brief (PWM_IER2) Comparison 6 Update Interrupt Enable */
#define PWM_IER2_CMPU7 (0x1u << 23) /**< \brief (PWM_IER2) Comparison 7 Update Interrupt Enable */
/* -------- PWM_IDR2 : (PWM Offset: 0x38) PWM Interrupt Disable Register 2 -------- */
#define PWM_IDR2_WRDY (0x1u << 0) /**< \brief (PWM_IDR2) Write Ready for Synchronous Channels Update Interrupt Disable */
#define PWM_IDR2_ENDTX (0x1u << 1) /**< \brief (PWM_IDR2) PDC End of TX Buffer Interrupt Disable */
#define PWM_IDR2_TXBUFE (0x1u << 2) /**< \brief (PWM_IDR2) PDC TX Buffer Empty Interrupt Disable */
#define PWM_IDR2_UNRE (0x1u << 3) /**< \brief (PWM_IDR2) Synchronous Channels Update Underrun Error Interrupt Disable */
#define PWM_IDR2_CMPM0 (0x1u << 8) /**< \brief (PWM_IDR2) Comparison 0 Match Interrupt Disable */
#define PWM_IDR2_CMPM1 (0x1u << 9) /**< \brief (PWM_IDR2) Comparison 1 Match Interrupt Disable */
#define PWM_IDR2_CMPM2 (0x1u << 10) /**< \brief (PWM_IDR2) Comparison 2 Match Interrupt Disable */
#define PWM_IDR2_CMPM3 (0x1u << 11) /**< \brief (PWM_IDR2) Comparison 3 Match Interrupt Disable */
#define PWM_IDR2_CMPM4 (0x1u << 12) /**< \brief (PWM_IDR2) Comparison 4 Match Interrupt Disable */
#define PWM_IDR2_CMPM5 (0x1u << 13) /**< \brief (PWM_IDR2) Comparison 5 Match Interrupt Disable */
#define PWM_IDR2_CMPM6 (0x1u << 14) /**< \brief (PWM_IDR2) Comparison 6 Match Interrupt Disable */
#define PWM_IDR2_CMPM7 (0x1u << 15) /**< \brief (PWM_IDR2) Comparison 7 Match Interrupt Disable */
#define PWM_IDR2_CMPU0 (0x1u << 16) /**< \brief (PWM_IDR2) Comparison 0 Update Interrupt Disable */
#define PWM_IDR2_CMPU1 (0x1u << 17) /**< \brief (PWM_IDR2) Comparison 1 Update Interrupt Disable */
#define PWM_IDR2_CMPU2 (0x1u << 18) /**< \brief (PWM_IDR2) Comparison 2 Update Interrupt Disable */
#define PWM_IDR2_CMPU3 (0x1u << 19) /**< \brief (PWM_IDR2) Comparison 3 Update Interrupt Disable */
#define PWM_IDR2_CMPU4 (0x1u << 20) /**< \brief (PWM_IDR2) Comparison 4 Update Interrupt Disable */
#define PWM_IDR2_CMPU5 (0x1u << 21) /**< \brief (PWM_IDR2) Comparison 5 Update Interrupt Disable */
#define PWM_IDR2_CMPU6 (0x1u << 22) /**< \brief (PWM_IDR2) Comparison 6 Update Interrupt Disable */
#define PWM_IDR2_CMPU7 (0x1u << 23) /**< \brief (PWM_IDR2) Comparison 7 Update Interrupt Disable */
/* -------- PWM_IMR2 : (PWM Offset: 0x3C) PWM Interrupt Mask Register 2 -------- */
#define PWM_IMR2_WRDY (0x1u << 0) /**< \brief (PWM_IMR2) Write Ready for Synchronous Channels Update Interrupt Mask */
#define PWM_IMR2_ENDTX (0x1u << 1) /**< \brief (PWM_IMR2) PDC End of TX Buffer Interrupt Mask */
#define PWM_IMR2_TXBUFE (0x1u << 2) /**< \brief (PWM_IMR2) PDC TX Buffer Empty Interrupt Mask */
#define PWM_IMR2_UNRE (0x1u << 3) /**< \brief (PWM_IMR2) Synchronous Channels Update Underrun Error Interrupt Mask */
#define PWM_IMR2_CMPM0 (0x1u << 8) /**< \brief (PWM_IMR2) Comparison 0 Match Interrupt Mask */
#define PWM_IMR2_CMPM1 (0x1u << 9) /**< \brief (PWM_IMR2) Comparison 1 Match Interrupt Mask */
#define PWM_IMR2_CMPM2 (0x1u << 10) /**< \brief (PWM_IMR2) Comparison 2 Match Interrupt Mask */
#define PWM_IMR2_CMPM3 (0x1u << 11) /**< \brief (PWM_IMR2) Comparison 3 Match Interrupt Mask */
#define PWM_IMR2_CMPM4 (0x1u << 12) /**< \brief (PWM_IMR2) Comparison 4 Match Interrupt Mask */
#define PWM_IMR2_CMPM5 (0x1u << 13) /**< \brief (PWM_IMR2) Comparison 5 Match Interrupt Mask */
#define PWM_IMR2_CMPM6 (0x1u << 14) /**< \brief (PWM_IMR2) Comparison 6 Match Interrupt Mask */
#define PWM_IMR2_CMPM7 (0x1u << 15) /**< \brief (PWM_IMR2) Comparison 7 Match Interrupt Mask */
#define PWM_IMR2_CMPU0 (0x1u << 16) /**< \brief (PWM_IMR2) Comparison 0 Update Interrupt Mask */
#define PWM_IMR2_CMPU1 (0x1u << 17) /**< \brief (PWM_IMR2) Comparison 1 Update Interrupt Mask */
#define PWM_IMR2_CMPU2 (0x1u << 18) /**< \brief (PWM_IMR2) Comparison 2 Update Interrupt Mask */
#define PWM_IMR2_CMPU3 (0x1u << 19) /**< \brief (PWM_IMR2) Comparison 3 Update Interrupt Mask */
#define PWM_IMR2_CMPU4 (0x1u << 20) /**< \brief (PWM_IMR2) Comparison 4 Update Interrupt Mask */
#define PWM_IMR2_CMPU5 (0x1u << 21) /**< \brief (PWM_IMR2) Comparison 5 Update Interrupt Mask */
#define PWM_IMR2_CMPU6 (0x1u << 22) /**< \brief (PWM_IMR2) Comparison 6 Update Interrupt Mask */
#define PWM_IMR2_CMPU7 (0x1u << 23) /**< \brief (PWM_IMR2) Comparison 7 Update Interrupt Mask */
/* -------- PWM_ISR2 : (PWM Offset: 0x40) PWM Interrupt Status Register 2 -------- */
#define PWM_ISR2_WRDY (0x1u << 0) /**< \brief (PWM_ISR2) Write Ready for Synchronous Channels Update */
#define PWM_ISR2_ENDTX (0x1u << 1) /**< \brief (PWM_ISR2) PDC End of TX Buffer */
#define PWM_ISR2_TXBUFE (0x1u << 2) /**< \brief (PWM_ISR2) PDC TX Buffer Empty */
#define PWM_ISR2_UNRE (0x1u << 3) /**< \brief (PWM_ISR2) Synchronous Channels Update Underrun Error */
#define PWM_ISR2_CMPM0 (0x1u << 8) /**< \brief (PWM_ISR2) Comparison 0 Match */
#define PWM_ISR2_CMPM1 (0x1u << 9) /**< \brief (PWM_ISR2) Comparison 1 Match */
#define PWM_ISR2_CMPM2 (0x1u << 10) /**< \brief (PWM_ISR2) Comparison 2 Match */
#define PWM_ISR2_CMPM3 (0x1u << 11) /**< \brief (PWM_ISR2) Comparison 3 Match */
#define PWM_ISR2_CMPM4 (0x1u << 12) /**< \brief (PWM_ISR2) Comparison 4 Match */
#define PWM_ISR2_CMPM5 (0x1u << 13) /**< \brief (PWM_ISR2) Comparison 5 Match */
#define PWM_ISR2_CMPM6 (0x1u << 14) /**< \brief (PWM_ISR2) Comparison 6 Match */
#define PWM_ISR2_CMPM7 (0x1u << 15) /**< \brief (PWM_ISR2) Comparison 7 Match */
#define PWM_ISR2_CMPU0 (0x1u << 16) /**< \brief (PWM_ISR2) Comparison 0 Update */
#define PWM_ISR2_CMPU1 (0x1u << 17) /**< \brief (PWM_ISR2) Comparison 1 Update */
#define PWM_ISR2_CMPU2 (0x1u << 18) /**< \brief (PWM_ISR2) Comparison 2 Update */
#define PWM_ISR2_CMPU3 (0x1u << 19) /**< \brief (PWM_ISR2) Comparison 3 Update */
#define PWM_ISR2_CMPU4 (0x1u << 20) /**< \brief (PWM_ISR2) Comparison 4 Update */
#define PWM_ISR2_CMPU5 (0x1u << 21) /**< \brief (PWM_ISR2) Comparison 5 Update */
#define PWM_ISR2_CMPU6 (0x1u << 22) /**< \brief (PWM_ISR2) Comparison 6 Update */
#define PWM_ISR2_CMPU7 (0x1u << 23) /**< \brief (PWM_ISR2) Comparison 7 Update */
/* -------- PWM_OOV : (PWM Offset: 0x44) PWM Output Override Value Register -------- */
#define PWM_OOV_OOVH0 (0x1u << 0) /**< \brief (PWM_OOV) Output Override Value for PWMH output of the channel 0 */
#define PWM_OOV_OOVH1 (0x1u << 1) /**< \brief (PWM_OOV) Output Override Value for PWMH output of the channel 1 */
#define PWM_OOV_OOVH2 (0x1u << 2) /**< \brief (PWM_OOV) Output Override Value for PWMH output of the channel 2 */
#define PWM_OOV_OOVH3 (0x1u << 3) /**< \brief (PWM_OOV) Output Override Value for PWMH output of the channel 3 */
#define PWM_OOV_OOVH4 (0x1u << 4) /**< \brief (PWM_OOV) Output Override Value for PWMH output of the channel 4 */
#define PWM_OOV_OOVH5 (0x1u << 5) /**< \brief (PWM_OOV) Output Override Value for PWMH output of the channel 5 */
#define PWM_OOV_OOVH6 (0x1u << 6) /**< \brief (PWM_OOV) Output Override Value for PWMH output of the channel 6 */
#define PWM_OOV_OOVH7 (0x1u << 7) /**< \brief (PWM_OOV) Output Override Value for PWMH output of the channel 7 */
#define PWM_OOV_OOVL0 (0x1u << 16) /**< \brief (PWM_OOV) Output Override Value for PWML output of the channel 0 */
#define PWM_OOV_OOVL1 (0x1u << 17) /**< \brief (PWM_OOV) Output Override Value for PWML output of the channel 1 */
#define PWM_OOV_OOVL2 (0x1u << 18) /**< \brief (PWM_OOV) Output Override Value for PWML output of the channel 2 */
#define PWM_OOV_OOVL3 (0x1u << 19) /**< \brief (PWM_OOV) Output Override Value for PWML output of the channel 3 */
#define PWM_OOV_OOVL4 (0x1u << 20) /**< \brief (PWM_OOV) Output Override Value for PWML output of the channel 4 */
#define PWM_OOV_OOVL5 (0x1u << 21) /**< \brief (PWM_OOV) Output Override Value for PWML output of the channel 5 */
#define PWM_OOV_OOVL6 (0x1u << 22) /**< \brief (PWM_OOV) Output Override Value for PWML output of the channel 6 */
#define PWM_OOV_OOVL7 (0x1u << 23) /**< \brief (PWM_OOV) Output Override Value for PWML output of the channel 7 */
/* -------- PWM_OS : (PWM Offset: 0x48) PWM Output Selection Register -------- */
#define PWM_OS_OSH0 (0x1u << 0) /**< \brief (PWM_OS) Output Selection for PWMH output of the channel 0 */
#define PWM_OS_OSH1 (0x1u << 1) /**< \brief (PWM_OS) Output Selection for PWMH output of the channel 1 */
#define PWM_OS_OSH2 (0x1u << 2) /**< \brief (PWM_OS) Output Selection for PWMH output of the channel 2 */
#define PWM_OS_OSH3 (0x1u << 3) /**< \brief (PWM_OS) Output Selection for PWMH output of the channel 3 */
#define PWM_OS_OSH4 (0x1u << 4) /**< \brief (PWM_OS) Output Selection for PWMH output of the channel 4 */
#define PWM_OS_OSH5 (0x1u << 5) /**< \brief (PWM_OS) Output Selection for PWMH output of the channel 5 */
#define PWM_OS_OSH6 (0x1u << 6) /**< \brief (PWM_OS) Output Selection for PWMH output of the channel 6 */
#define PWM_OS_OSH7 (0x1u << 7) /**< \brief (PWM_OS) Output Selection for PWMH output of the channel 7 */
#define PWM_OS_OSL0 (0x1u << 16) /**< \brief (PWM_OS) Output Selection for PWML output of the channel 0 */
#define PWM_OS_OSL1 (0x1u << 17) /**< \brief (PWM_OS) Output Selection for PWML output of the channel 1 */
#define PWM_OS_OSL2 (0x1u << 18) /**< \brief (PWM_OS) Output Selection for PWML output of the channel 2 */
#define PWM_OS_OSL3 (0x1u << 19) /**< \brief (PWM_OS) Output Selection for PWML output of the channel 3 */
#define PWM_OS_OSL4 (0x1u << 20) /**< \brief (PWM_OS) Output Selection for PWML output of the channel 4 */
#define PWM_OS_OSL5 (0x1u << 21) /**< \brief (PWM_OS) Output Selection for PWML output of the channel 5 */
#define PWM_OS_OSL6 (0x1u << 22) /**< \brief (PWM_OS) Output Selection for PWML output of the channel 6 */
#define PWM_OS_OSL7 (0x1u << 23) /**< \brief (PWM_OS) Output Selection for PWML output of the channel 7 */
/* -------- PWM_OSS : (PWM Offset: 0x4C) PWM Output Selection Set Register -------- */
#define PWM_OSS_OSSH0 (0x1u << 0) /**< \brief (PWM_OSS) Output Selection Set for PWMH output of the channel 0 */
#define PWM_OSS_OSSH1 (0x1u << 1) /**< \brief (PWM_OSS) Output Selection Set for PWMH output of the channel 1 */
#define PWM_OSS_OSSH2 (0x1u << 2) /**< \brief (PWM_OSS) Output Selection Set for PWMH output of the channel 2 */
#define PWM_OSS_OSSH3 (0x1u << 3) /**< \brief (PWM_OSS) Output Selection Set for PWMH output of the channel 3 */
#define PWM_OSS_OSSH4 (0x1u << 4) /**< \brief (PWM_OSS) Output Selection Set for PWMH output of the channel 4 */
#define PWM_OSS_OSSH5 (0x1u << 5) /**< \brief (PWM_OSS) Output Selection Set for PWMH output of the channel 5 */
#define PWM_OSS_OSSH6 (0x1u << 6) /**< \brief (PWM_OSS) Output Selection Set for PWMH output of the channel 6 */
#define PWM_OSS_OSSH7 (0x1u << 7) /**< \brief (PWM_OSS) Output Selection Set for PWMH output of the channel 7 */
#define PWM_OSS_OSSL0 (0x1u << 16) /**< \brief (PWM_OSS) Output Selection Set for PWML output of the channel 0 */
#define PWM_OSS_OSSL1 (0x1u << 17) /**< \brief (PWM_OSS) Output Selection Set for PWML output of the channel 1 */
#define PWM_OSS_OSSL2 (0x1u << 18) /**< \brief (PWM_OSS) Output Selection Set for PWML output of the channel 2 */
#define PWM_OSS_OSSL3 (0x1u << 19) /**< \brief (PWM_OSS) Output Selection Set for PWML output of the channel 3 */
#define PWM_OSS_OSSL4 (0x1u << 20) /**< \brief (PWM_OSS) Output Selection Set for PWML output of the channel 4 */
#define PWM_OSS_OSSL5 (0x1u << 21) /**< \brief (PWM_OSS) Output Selection Set for PWML output of the channel 5 */
#define PWM_OSS_OSSL6 (0x1u << 22) /**< \brief (PWM_OSS) Output Selection Set for PWML output of the channel 6 */
#define PWM_OSS_OSSL7 (0x1u << 23) /**< \brief (PWM_OSS) Output Selection Set for PWML output of the channel 7 */
/* -------- PWM_OSC : (PWM Offset: 0x50) PWM Output Selection Clear Register -------- */
#define PWM_OSC_OSCH0 (0x1u << 0) /**< \brief (PWM_OSC) Output Selection Clear for PWMH output of the channel 0 */
#define PWM_OSC_OSCH1 (0x1u << 1) /**< \brief (PWM_OSC) Output Selection Clear for PWMH output of the channel 1 */
#define PWM_OSC_OSCH2 (0x1u << 2) /**< \brief (PWM_OSC) Output Selection Clear for PWMH output of the channel 2 */
#define PWM_OSC_OSCH3 (0x1u << 3) /**< \brief (PWM_OSC) Output Selection Clear for PWMH output of the channel 3 */
#define PWM_OSC_OSCH4 (0x1u << 4) /**< \brief (PWM_OSC) Output Selection Clear for PWMH output of the channel 4 */
#define PWM_OSC_OSCH5 (0x1u << 5) /**< \brief (PWM_OSC) Output Selection Clear for PWMH output of the channel 5 */
#define PWM_OSC_OSCH6 (0x1u << 6) /**< \brief (PWM_OSC) Output Selection Clear for PWMH output of the channel 6 */
#define PWM_OSC_OSCH7 (0x1u << 7) /**< \brief (PWM_OSC) Output Selection Clear for PWMH output of the channel 7 */
#define PWM_OSC_OSCL0 (0x1u << 16) /**< \brief (PWM_OSC) Output Selection Clear for PWML output of the channel 0 */
#define PWM_OSC_OSCL1 (0x1u << 17) /**< \brief (PWM_OSC) Output Selection Clear for PWML output of the channel 1 */
#define PWM_OSC_OSCL2 (0x1u << 18) /**< \brief (PWM_OSC) Output Selection Clear for PWML output of the channel 2 */
#define PWM_OSC_OSCL3 (0x1u << 19) /**< \brief (PWM_OSC) Output Selection Clear for PWML output of the channel 3 */
#define PWM_OSC_OSCL4 (0x1u << 20) /**< \brief (PWM_OSC) Output Selection Clear for PWML output of the channel 4 */
#define PWM_OSC_OSCL5 (0x1u << 21) /**< \brief (PWM_OSC) Output Selection Clear for PWML output of the channel 5 */
#define PWM_OSC_OSCL6 (0x1u << 22) /**< \brief (PWM_OSC) Output Selection Clear for PWML output of the channel 6 */
#define PWM_OSC_OSCL7 (0x1u << 23) /**< \brief (PWM_OSC) Output Selection Clear for PWML output of the channel 7 */
/* -------- PWM_OSSUPD : (PWM Offset: 0x54) PWM Output Selection Set Update Register -------- */
#define PWM_OSSUPD_OSSUPH0 (0x1u << 0) /**< \brief (PWM_OSSUPD) Output Selection Set for PWMH output of the channel 0 */
#define PWM_OSSUPD_OSSUPH1 (0x1u << 1) /**< \brief (PWM_OSSUPD) Output Selection Set for PWMH output of the channel 1 */
#define PWM_OSSUPD_OSSUPH2 (0x1u << 2) /**< \brief (PWM_OSSUPD) Output Selection Set for PWMH output of the channel 2 */
#define PWM_OSSUPD_OSSUPH3 (0x1u << 3) /**< \brief (PWM_OSSUPD) Output Selection Set for PWMH output of the channel 3 */
#define PWM_OSSUPD_OSSUPH4 (0x1u << 4) /**< \brief (PWM_OSSUPD) Output Selection Set for PWMH output of the channel 4 */
#define PWM_OSSUPD_OSSUPH5 (0x1u << 5) /**< \brief (PWM_OSSUPD) Output Selection Set for PWMH output of the channel 5 */
#define PWM_OSSUPD_OSSUPH6 (0x1u << 6) /**< \brief (PWM_OSSUPD) Output Selection Set for PWMH output of the channel 6 */
#define PWM_OSSUPD_OSSUPH7 (0x1u << 7) /**< \brief (PWM_OSSUPD) Output Selection Set for PWMH output of the channel 7 */
#define PWM_OSSUPD_OSSUPL0 (0x1u << 16) /**< \brief (PWM_OSSUPD) Output Selection Set for PWML output of the channel 0 */
#define PWM_OSSUPD_OSSUPL1 (0x1u << 17) /**< \brief (PWM_OSSUPD) Output Selection Set for PWML output of the channel 1 */
#define PWM_OSSUPD_OSSUPL2 (0x1u << 18) /**< \brief (PWM_OSSUPD) Output Selection Set for PWML output of the channel 2 */
#define PWM_OSSUPD_OSSUPL3 (0x1u << 19) /**< \brief (PWM_OSSUPD) Output Selection Set for PWML output of the channel 3 */
#define PWM_OSSUPD_OSSUPL4 (0x1u << 20) /**< \brief (PWM_OSSUPD) Output Selection Set for PWML output of the channel 4 */
#define PWM_OSSUPD_OSSUPL5 (0x1u << 21) /**< \brief (PWM_OSSUPD) Output Selection Set for PWML output of the channel 5 */
#define PWM_OSSUPD_OSSUPL6 (0x1u << 22) /**< \brief (PWM_OSSUPD) Output Selection Set for PWML output of the channel 6 */
#define PWM_OSSUPD_OSSUPL7 (0x1u << 23) /**< \brief (PWM_OSSUPD) Output Selection Set for PWML output of the channel 7 */
/* -------- PWM_OSCUPD : (PWM Offset: 0x58) PWM Output Selection Clear Update Register -------- */
#define PWM_OSCUPD_OSCUPH0 (0x1u << 0) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWMH output of the channel 0 */
#define PWM_OSCUPD_OSCUPH1 (0x1u << 1) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWMH output of the channel 1 */
#define PWM_OSCUPD_OSCUPH2 (0x1u << 2) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWMH output of the channel 2 */
#define PWM_OSCUPD_OSCUPH3 (0x1u << 3) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWMH output of the channel 3 */
#define PWM_OSCUPD_OSCUPH4 (0x1u << 4) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWMH output of the channel 4 */
#define PWM_OSCUPD_OSCUPH5 (0x1u << 5) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWMH output of the channel 5 */
#define PWM_OSCUPD_OSCUPH6 (0x1u << 6) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWMH output of the channel 6 */
#define PWM_OSCUPD_OSCUPH7 (0x1u << 7) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWMH output of the channel 7 */
#define PWM_OSCUPD_OSCUPL0 (0x1u << 16) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWML output of the channel 0 */
#define PWM_OSCUPD_OSCUPL1 (0x1u << 17) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWML output of the channel 1 */
#define PWM_OSCUPD_OSCUPL2 (0x1u << 18) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWML output of the channel 2 */
#define PWM_OSCUPD_OSCUPL3 (0x1u << 19) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWML output of the channel 3 */
#define PWM_OSCUPD_OSCUPL4 (0x1u << 20) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWML output of the channel 4 */
#define PWM_OSCUPD_OSCUPL5 (0x1u << 21) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWML output of the channel 5 */
#define PWM_OSCUPD_OSCUPDL6 (0x1u << 22) /**< \brief (PWM_OSCUPD) */
#define PWM_OSCUPD_OSCUPL7 (0x1u << 23) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWML output of the channel 7 */
/* -------- PWM_FMR : (PWM Offset: 0x5C) PWM Fault Mode Register -------- */
#define PWM_FMR_FPOL_Pos 0
#define PWM_FMR_FPOL_Msk (0xffu << PWM_FMR_FPOL_Pos) /**< \brief (PWM_FMR) Fault Polarity (fault input bit varies from 0 to 5) */
#define PWM_FMR_FPOL(value) ((PWM_FMR_FPOL_Msk & ((value) << PWM_FMR_FPOL_Pos)))
#define PWM_FMR_FMOD_Pos 8
#define PWM_FMR_FMOD_Msk (0xffu << PWM_FMR_FMOD_Pos) /**< \brief (PWM_FMR) Fault Activation Mode (fault input bit varies from 0 to 5) */
#define PWM_FMR_FMOD(value) ((PWM_FMR_FMOD_Msk & ((value) << PWM_FMR_FMOD_Pos)))
#define PWM_FMR_FFIL_Pos 16
#define PWM_FMR_FFIL_Msk (0xffu << PWM_FMR_FFIL_Pos) /**< \brief (PWM_FMR) Fault Filtering (fault input bit varies from 0 to 5) */
#define PWM_FMR_FFIL(value) ((PWM_FMR_FFIL_Msk & ((value) << PWM_FMR_FFIL_Pos)))
/* -------- PWM_FSR : (PWM Offset: 0x60) PWM Fault Status Register -------- */
#define PWM_FSR_FIV_Pos 0
#define PWM_FSR_FIV_Msk (0xffu << PWM_FSR_FIV_Pos) /**< \brief (PWM_FSR) Fault Input Value (fault input bit varies from 0 to 5) */
#define PWM_FSR_FS_Pos 8
#define PWM_FSR_FS_Msk (0xffu << PWM_FSR_FS_Pos) /**< \brief (PWM_FSR) Fault Status (fault input bit varies from 0 to 5) */
/* -------- PWM_FCR : (PWM Offset: 0x64) PWM Fault Clear Register -------- */
#define PWM_FCR_FCLR_Pos 0
#define PWM_FCR_FCLR_Msk (0xffu << PWM_FCR_FCLR_Pos) /**< \brief (PWM_FCR) Fault Clear (fault input bit varies from 0 to 5) */
#define PWM_FCR_FCLR(value) ((PWM_FCR_FCLR_Msk & ((value) << PWM_FCR_FCLR_Pos)))
/* -------- PWM_FPV : (PWM Offset: 0x68) PWM Fault Protection Value Register -------- */
#define PWM_FPV_FPVH0 (0x1u << 0) /**< \brief (PWM_FPV) Fault Protection Value for PWMH output on channel 0 */
#define PWM_FPV_FPVH1 (0x1u << 1) /**< \brief (PWM_FPV) Fault Protection Value for PWMH output on channel 1 */
#define PWM_FPV_FPVH2 (0x1u << 2) /**< \brief (PWM_FPV) Fault Protection Value for PWMH output on channel 2 */
#define PWM_FPV_FPVH3 (0x1u << 3) /**< \brief (PWM_FPV) Fault Protection Value for PWMH output on channel 3 */
#define PWM_FPV_FPVH4 (0x1u << 4) /**< \brief (PWM_FPV) Fault Protection Value for PWMH output on channel 4 */
#define PWM_FPV_FPVH5 (0x1u << 5) /**< \brief (PWM_FPV) Fault Protection Value for PWMH output on channel 5 */
#define PWM_FPV_FPVH6 (0x1u << 6) /**< \brief (PWM_FPV) Fault Protection Value for PWMH output on channel 6 */
#define PWM_FPV_FPVH7 (0x1u << 7) /**< \brief (PWM_FPV) Fault Protection Value for PWMH output on channel 7 */
#define PWM_FPV_FPVL0 (0x1u << 16) /**< \brief (PWM_FPV) Fault Protection Value for PWML output on channel 0 */
#define PWM_FPV_FPVL1 (0x1u << 17) /**< \brief (PWM_FPV) Fault Protection Value for PWML output on channel 1 */
#define PWM_FPV_FPVL2 (0x1u << 18) /**< \brief (PWM_FPV) Fault Protection Value for PWML output on channel 2 */
#define PWM_FPV_FPVL3 (0x1u << 19) /**< \brief (PWM_FPV) Fault Protection Value for PWML output on channel 3 */
#define PWM_FPV_FPVL4 (0x1u << 20) /**< \brief (PWM_FPV) Fault Protection Value for PWML output on channel 4 */
#define PWM_FPV_FPVL5 (0x1u << 21) /**< \brief (PWM_FPV) Fault Protection Value for PWML output on channel 5 */
#define PWM_FPV_FPVL6 (0x1u << 22) /**< \brief (PWM_FPV) Fault Protection Value for PWML output on channel 6 */
#define PWM_FPV_FPVL7 (0x1u << 23) /**< \brief (PWM_FPV) Fault Protection Value for PWML output on channel 7 */
/* -------- PWM_FPE1 : (PWM Offset: 0x6C) PWM Fault Protection Enable Register 1 -------- */
#define PWM_FPE1_FPE0_Pos 0
#define PWM_FPE1_FPE0_Msk (0xffu << PWM_FPE1_FPE0_Pos) /**< \brief (PWM_FPE1) Fault Protection Enable for channel 0 (fault input bit varies from 0 to 5) */
#define PWM_FPE1_FPE0(value) ((PWM_FPE1_FPE0_Msk & ((value) << PWM_FPE1_FPE0_Pos)))
#define PWM_FPE1_FPE1_Pos 8
#define PWM_FPE1_FPE1_Msk (0xffu << PWM_FPE1_FPE1_Pos) /**< \brief (PWM_FPE1) Fault Protection Enable for channel 1 (fault input bit varies from 0 to 5) */
#define PWM_FPE1_FPE1(value) ((PWM_FPE1_FPE1_Msk & ((value) << PWM_FPE1_FPE1_Pos)))
#define PWM_FPE1_FPE2_Pos 16
#define PWM_FPE1_FPE2_Msk (0xffu << PWM_FPE1_FPE2_Pos) /**< \brief (PWM_FPE1) Fault Protection Enable for channel 2 (fault input bit varies from 0 to 5) */
#define PWM_FPE1_FPE2(value) ((PWM_FPE1_FPE2_Msk & ((value) << PWM_FPE1_FPE2_Pos)))
#define PWM_FPE1_FPE3_Pos 24
#define PWM_FPE1_FPE3_Msk (0xffu << PWM_FPE1_FPE3_Pos) /**< \brief (PWM_FPE1) Fault Protection Enable for channel 3 (fault input bit varies from 0 to 5) */
#define PWM_FPE1_FPE3(value) ((PWM_FPE1_FPE3_Msk & ((value) << PWM_FPE1_FPE3_Pos)))
/* -------- PWM_FPE2 : (PWM Offset: 0x70) PWM Fault Protection Enable Register 2 -------- */
#define PWM_FPE2_FPE4_Pos 0
#define PWM_FPE2_FPE4_Msk (0xffu << PWM_FPE2_FPE4_Pos) /**< \brief (PWM_FPE2) Fault Protection Enable for channel 4 (fault input bit varies from 0 to 5) */
#define PWM_FPE2_FPE4(value) ((PWM_FPE2_FPE4_Msk & ((value) << PWM_FPE2_FPE4_Pos)))
#define PWM_FPE2_FPE5_Pos 8
#define PWM_FPE2_FPE5_Msk (0xffu << PWM_FPE2_FPE5_Pos) /**< \brief (PWM_FPE2) Fault Protection Enable for channel 5 (fault input bit varies from 0 to 5) */
#define PWM_FPE2_FPE5(value) ((PWM_FPE2_FPE5_Msk & ((value) << PWM_FPE2_FPE5_Pos)))
#define PWM_FPE2_FPE6_Pos 16
#define PWM_FPE2_FPE6_Msk (0xffu << PWM_FPE2_FPE6_Pos) /**< \brief (PWM_FPE2) Fault Protection Enable for channel 6 (fault input bit varies from 0 to 5) */
#define PWM_FPE2_FPE6(value) ((PWM_FPE2_FPE6_Msk & ((value) << PWM_FPE2_FPE6_Pos)))
#define PWM_FPE2_FPE7_Pos 24
#define PWM_FPE2_FPE7_Msk (0xffu << PWM_FPE2_FPE7_Pos) /**< \brief (PWM_FPE2) Fault Protection Enable for channel 7 (fault input bit varies from 0 to 5) */
#define PWM_FPE2_FPE7(value) ((PWM_FPE2_FPE7_Msk & ((value) << PWM_FPE2_FPE7_Pos)))
/* -------- PWM_ELMR[2] : (PWM Offset: 0x7C) PWM Event Line 0 Mode Register -------- */
#define PWM_ELMR_CSEL0 (0x1u << 0) /**< \brief (PWM_ELMR[2]) Comparison 0 Selection */
#define PWM_ELMR_CSEL1 (0x1u << 1) /**< \brief (PWM_ELMR[2]) Comparison 1 Selection */
#define PWM_ELMR_CSEL2 (0x1u << 2) /**< \brief (PWM_ELMR[2]) Comparison 2 Selection */
#define PWM_ELMR_CSEL3 (0x1u << 3) /**< \brief (PWM_ELMR[2]) Comparison 3 Selection */
#define PWM_ELMR_CSEL4 (0x1u << 4) /**< \brief (PWM_ELMR[2]) Comparison 4 Selection */
#define PWM_ELMR_CSEL5 (0x1u << 5) /**< \brief (PWM_ELMR[2]) Comparison 5 Selection */
#define PWM_ELMR_CSEL6 (0x1u << 6) /**< \brief (PWM_ELMR[2]) Comparison 6 Selection */
#define PWM_ELMR_CSEL7 (0x1u << 7) /**< \brief (PWM_ELMR[2]) Comparison 7 Selection */
/* -------- PWM_SMMR : (PWM Offset: 0xB0) PWM Stepper Motor Mode Register -------- */
#define PWM_SMMR_GCEN0 (0x1u << 0) /**< \brief (PWM_SMMR) Gray Count ENable */
#define PWM_SMMR_GCEN1 (0x1u << 1) /**< \brief (PWM_SMMR) Gray Count ENable */
#define PWM_SMMR_GCEN2 (0x1u << 2) /**< \brief (PWM_SMMR) Gray Count ENable */
#define PWM_SMMR_GCEN3 (0x1u << 3) /**< \brief (PWM_SMMR) Gray Count ENable */
#define PWM_SMMR_DOWN0 (0x1u << 16) /**< \brief (PWM_SMMR) DOWN Count */
#define PWM_SMMR_DOWN1 (0x1u << 17) /**< \brief (PWM_SMMR) DOWN Count */
#define PWM_SMMR_DOWN2 (0x1u << 18) /**< \brief (PWM_SMMR) DOWN Count */
#define PWM_SMMR_DOWN3 (0x1u << 19) /**< \brief (PWM_SMMR) DOWN Count */
/* -------- PWM_WPCR : (PWM Offset: 0xE4) PWM Write Protect Control Register -------- */
#define PWM_WPCR_WPCMD_Pos 0
#define PWM_WPCR_WPCMD_Msk (0x3u << PWM_WPCR_WPCMD_Pos) /**< \brief (PWM_WPCR) Write Protect Command */
#define PWM_WPCR_WPCMD(value) ((PWM_WPCR_WPCMD_Msk & ((value) << PWM_WPCR_WPCMD_Pos)))
#define PWM_WPCR_WPRG0 (0x1u << 2) /**< \brief (PWM_WPCR) Write Protect Register Group 0 */
#define PWM_WPCR_WPRG1 (0x1u << 3) /**< \brief (PWM_WPCR) Write Protect Register Group 1 */
#define PWM_WPCR_WPRG2 (0x1u << 4) /**< \brief (PWM_WPCR) Write Protect Register Group 2 */
#define PWM_WPCR_WPRG3 (0x1u << 5) /**< \brief (PWM_WPCR) Write Protect Register Group 3 */
#define PWM_WPCR_WPRG4 (0x1u << 6) /**< \brief (PWM_WPCR) Write Protect Register Group 4 */
#define PWM_WPCR_WPRG5 (0x1u << 7) /**< \brief (PWM_WPCR) Write Protect Register Group 5 */
#define PWM_WPCR_WPKEY_Pos 8
#define PWM_WPCR_WPKEY_Msk (0xffffffu << PWM_WPCR_WPKEY_Pos) /**< \brief (PWM_WPCR) Write Protect Key */
#define PWM_WPCR_WPKEY(value) ((PWM_WPCR_WPKEY_Msk & ((value) << PWM_WPCR_WPKEY_Pos)))
/* -------- PWM_WPSR : (PWM Offset: 0xE8) PWM Write Protect Status Register -------- */
#define PWM_WPSR_WPSWS0 (0x1u << 0) /**< \brief (PWM_WPSR) Write Protect SW Status */
#define PWM_WPSR_WPSWS1 (0x1u << 1) /**< \brief (PWM_WPSR) Write Protect SW Status */
#define PWM_WPSR_WPSWS2 (0x1u << 2) /**< \brief (PWM_WPSR) Write Protect SW Status */
#define PWM_WPSR_WPSWS3 (0x1u << 3) /**< \brief (PWM_WPSR) Write Protect SW Status */
#define PWM_WPSR_WPSWS4 (0x1u << 4) /**< \brief (PWM_WPSR) Write Protect SW Status */
#define PWM_WPSR_WPSWS5 (0x1u << 5) /**< \brief (PWM_WPSR) Write Protect SW Status */
#define PWM_WPSR_WPVS (0x1u << 7) /**< \brief (PWM_WPSR) Write Protect Violation Status */
#define PWM_WPSR_WPHWS0 (0x1u << 8) /**< \brief (PWM_WPSR) Write Protect HW Status */
#define PWM_WPSR_WPHWS1 (0x1u << 9) /**< \brief (PWM_WPSR) Write Protect HW Status */
#define PWM_WPSR_WPHWS2 (0x1u << 10) /**< \brief (PWM_WPSR) Write Protect HW Status */
#define PWM_WPSR_WPHWS3 (0x1u << 11) /**< \brief (PWM_WPSR) Write Protect HW Status */
#define PWM_WPSR_WPHWS4 (0x1u << 12) /**< \brief (PWM_WPSR) Write Protect HW Status */
#define PWM_WPSR_WPHWS5 (0x1u << 13) /**< \brief (PWM_WPSR) Write Protect HW Status */
#define PWM_WPSR_WPVSRC_Pos 16
#define PWM_WPSR_WPVSRC_Msk (0xffffu << PWM_WPSR_WPVSRC_Pos) /**< \brief (PWM_WPSR) Write Protect Violation Source */
/* -------- PWM_TPR : (PWM Offset: 0x108) Transmit Pointer Register -------- */
#define PWM_TPR_TXPTR_Pos 0
#define PWM_TPR_TXPTR_Msk (0xffffffffu << PWM_TPR_TXPTR_Pos) /**< \brief (PWM_TPR) Transmit Counter Register */
#define PWM_TPR_TXPTR(value) ((PWM_TPR_TXPTR_Msk & ((value) << PWM_TPR_TXPTR_Pos)))
/* -------- PWM_TCR : (PWM Offset: 0x10C) Transmit Counter Register -------- */
#define PWM_TCR_TXCTR_Pos 0
#define PWM_TCR_TXCTR_Msk (0xffffu << PWM_TCR_TXCTR_Pos) /**< \brief (PWM_TCR) Transmit Counter Register */
#define PWM_TCR_TXCTR(value) ((PWM_TCR_TXCTR_Msk & ((value) << PWM_TCR_TXCTR_Pos)))
/* -------- PWM_TNPR : (PWM Offset: 0x118) Transmit Next Pointer Register -------- */
#define PWM_TNPR_TXNPTR_Pos 0
#define PWM_TNPR_TXNPTR_Msk (0xffffffffu << PWM_TNPR_TXNPTR_Pos) /**< \brief (PWM_TNPR) Transmit Next Pointer */
#define PWM_TNPR_TXNPTR(value) ((PWM_TNPR_TXNPTR_Msk & ((value) << PWM_TNPR_TXNPTR_Pos)))
/* -------- PWM_TNCR : (PWM Offset: 0x11C) Transmit Next Counter Register -------- */
#define PWM_TNCR_TXNCTR_Pos 0
#define PWM_TNCR_TXNCTR_Msk (0xffffu << PWM_TNCR_TXNCTR_Pos) /**< \brief (PWM_TNCR) Transmit Counter Next */
#define PWM_TNCR_TXNCTR(value) ((PWM_TNCR_TXNCTR_Msk & ((value) << PWM_TNCR_TXNCTR_Pos)))
/* -------- PWM_PTCR : (PWM Offset: 0x120) Transfer Control Register -------- */
#define PWM_PTCR_RXTEN (0x1u << 0) /**< \brief (PWM_PTCR) Receiver Transfer Enable */
#define PWM_PTCR_RXTDIS (0x1u << 1) /**< \brief (PWM_PTCR) Receiver Transfer Disable */
#define PWM_PTCR_TXTEN (0x1u << 8) /**< \brief (PWM_PTCR) Transmitter Transfer Enable */
#define PWM_PTCR_TXTDIS (0x1u << 9) /**< \brief (PWM_PTCR) Transmitter Transfer Disable */
/* -------- PWM_PTSR : (PWM Offset: 0x124) Transfer Status Register -------- */
#define PWM_PTSR_RXTEN (0x1u << 0) /**< \brief (PWM_PTSR) Receiver Transfer Enable */
#define PWM_PTSR_TXTEN (0x1u << 8) /**< \brief (PWM_PTSR) Transmitter Transfer Enable */
/* -------- PWM_CMPV : (PWM Offset: N/A) PWM Comparison 0 Value Register -------- */
#define PWM_CMPV_CV_Pos 0
#define PWM_CMPV_CV_Msk (0xffffffu << PWM_CMPV_CV_Pos) /**< \brief (PWM_CMPV) Comparison x Value */
#define PWM_CMPV_CV(value) ((PWM_CMPV_CV_Msk & ((value) << PWM_CMPV_CV_Pos)))
#define PWM_CMPV_CVM (0x1u << 24) /**< \brief (PWM_CMPV) Comparison x Value Mode */
/* -------- PWM_CMPVUPD : (PWM Offset: N/A) PWM Comparison 0 Value Update Register -------- */
#define PWM_CMPVUPD_CVUPD_Pos 0
#define PWM_CMPVUPD_CVUPD_Msk (0xffffffu << PWM_CMPVUPD_CVUPD_Pos) /**< \brief (PWM_CMPVUPD) Comparison x Value Update */
#define PWM_CMPVUPD_CVUPD(value) ((PWM_CMPVUPD_CVUPD_Msk & ((value) << PWM_CMPVUPD_CVUPD_Pos)))
#define PWM_CMPVUPD_CVMUPD (0x1u << 24) /**< \brief (PWM_CMPVUPD) Comparison x Value Mode Update */
/* -------- PWM_CMPM : (PWM Offset: N/A) PWM Comparison 0 Mode Register -------- */
#define PWM_CMPM_CEN (0x1u << 0) /**< \brief (PWM_CMPM) Comparison x Enable */
#define PWM_CMPM_CTR_Pos 4
#define PWM_CMPM_CTR_Msk (0xfu << PWM_CMPM_CTR_Pos) /**< \brief (PWM_CMPM) Comparison x Trigger */
#define PWM_CMPM_CTR(value) ((PWM_CMPM_CTR_Msk & ((value) << PWM_CMPM_CTR_Pos)))
#define PWM_CMPM_CPR_Pos 8
#define PWM_CMPM_CPR_Msk (0xfu << PWM_CMPM_CPR_Pos) /**< \brief (PWM_CMPM) Comparison x Period */
#define PWM_CMPM_CPR(value) ((PWM_CMPM_CPR_Msk & ((value) << PWM_CMPM_CPR_Pos)))
#define PWM_CMPM_CPRCNT_Pos 12
#define PWM_CMPM_CPRCNT_Msk (0xfu << PWM_CMPM_CPRCNT_Pos) /**< \brief (PWM_CMPM) Comparison x Period Counter */
#define PWM_CMPM_CPRCNT(value) ((PWM_CMPM_CPRCNT_Msk & ((value) << PWM_CMPM_CPRCNT_Pos)))
#define PWM_CMPM_CUPR_Pos 16
#define PWM_CMPM_CUPR_Msk (0xfu << PWM_CMPM_CUPR_Pos) /**< \brief (PWM_CMPM) Comparison x Update Period */
#define PWM_CMPM_CUPR(value) ((PWM_CMPM_CUPR_Msk & ((value) << PWM_CMPM_CUPR_Pos)))
#define PWM_CMPM_CUPRCNT_Pos 20
#define PWM_CMPM_CUPRCNT_Msk (0xfu << PWM_CMPM_CUPRCNT_Pos) /**< \brief (PWM_CMPM) Comparison x Update Period Counter */
#define PWM_CMPM_CUPRCNT(value) ((PWM_CMPM_CUPRCNT_Msk & ((value) << PWM_CMPM_CUPRCNT_Pos)))
/* -------- PWM_CMPMUPD : (PWM Offset: N/A) PWM Comparison 0 Mode Update Register -------- */
#define PWM_CMPMUPD_CENUPD (0x1u << 0) /**< \brief (PWM_CMPMUPD) Comparison x Enable Update */
#define PWM_CMPMUPD_CTRUPD_Pos 4
#define PWM_CMPMUPD_CTRUPD_Msk (0xfu << PWM_CMPMUPD_CTRUPD_Pos) /**< \brief (PWM_CMPMUPD) Comparison x Trigger Update */
#define PWM_CMPMUPD_CTRUPD(value) ((PWM_CMPMUPD_CTRUPD_Msk & ((value) << PWM_CMPMUPD_CTRUPD_Pos)))
#define PWM_CMPMUPD_CPRUPD_Pos 8
#define PWM_CMPMUPD_CPRUPD_Msk (0xfu << PWM_CMPMUPD_CPRUPD_Pos) /**< \brief (PWM_CMPMUPD) Comparison x Period Update */
#define PWM_CMPMUPD_CPRUPD(value) ((PWM_CMPMUPD_CPRUPD_Msk & ((value) << PWM_CMPMUPD_CPRUPD_Pos)))
#define PWM_CMPMUPD_CUPRUPD_Pos 16
#define PWM_CMPMUPD_CUPRUPD_Msk (0xfu << PWM_CMPMUPD_CUPRUPD_Pos) /**< \brief (PWM_CMPMUPD) Comparison x Update Period Update */
#define PWM_CMPMUPD_CUPRUPD(value) ((PWM_CMPMUPD_CUPRUPD_Msk & ((value) << PWM_CMPMUPD_CUPRUPD_Pos)))
/* -------- PWM_CMR : (PWM Offset: N/A) PWM Channel Mode Register -------- */
#define PWM_CMR_CPRE_Pos 0
#define PWM_CMR_CPRE_Msk (0xfu << PWM_CMR_CPRE_Pos) /**< \brief (PWM_CMR) Channel Pre-scaler */
#define PWM_CMR_CPRE_MCK (0x0u << 0) /**< \brief (PWM_CMR) Master clock */
#define PWM_CMR_CPRE_MCK_DIV_2 (0x1u << 0) /**< \brief (PWM_CMR) Master clock/2 */
#define PWM_CMR_CPRE_MCK_DIV_4 (0x2u << 0) /**< \brief (PWM_CMR) Master clock/4 */
#define PWM_CMR_CPRE_MCK_DIV_8 (0x3u << 0) /**< \brief (PWM_CMR) Master clock/8 */
#define PWM_CMR_CPRE_MCK_DIV_16 (0x4u << 0) /**< \brief (PWM_CMR) Master clock/16 */
#define PWM_CMR_CPRE_MCK_DIV_32 (0x5u << 0) /**< \brief (PWM_CMR) Master clock/32 */
#define PWM_CMR_CPRE_MCK_DIV_64 (0x6u << 0) /**< \brief (PWM_CMR) Master clock/64 */
#define PWM_CMR_CPRE_MCK_DIV_128 (0x7u << 0) /**< \brief (PWM_CMR) Master clock/128 */
#define PWM_CMR_CPRE_MCK_DIV_256 (0x8u << 0) /**< \brief (PWM_CMR) Master clock/256 */
#define PWM_CMR_CPRE_MCK_DIV_512 (0x9u << 0) /**< \brief (PWM_CMR) Master clock/512 */
#define PWM_CMR_CPRE_MCK_DIV_1024 (0xAu << 0) /**< \brief (PWM_CMR) Master clock/1024 */
#define PWM_CMR_CPRE_CLKA (0xBu << 0) /**< \brief (PWM_CMR) Clock A */
#define PWM_CMR_CPRE_CLKB (0xCu << 0) /**< \brief (PWM_CMR) Clock B */
#define PWM_CMR_CALG (0x1u << 8) /**< \brief (PWM_CMR) Channel Alignment */
#define PWM_CMR_CPOL (0x1u << 9) /**< \brief (PWM_CMR) Channel Polarity */
#define PWM_CMR_CES (0x1u << 10) /**< \brief (PWM_CMR) Counter Event Selection */
#define PWM_CMR_DTE (0x1u << 16) /**< \brief (PWM_CMR) Dead-Time Generator Enable */
#define PWM_CMR_DTHI (0x1u << 17) /**< \brief (PWM_CMR) Dead-Time PWMHx Output Inverted */
#define PWM_CMR_DTLI (0x1u << 18) /**< \brief (PWM_CMR) Dead-Time PWMLx Output Inverted */
/* -------- PWM_CDTY : (PWM Offset: N/A) PWM Channel Duty Cycle Register -------- */
#define PWM_CDTY_CDTY_Pos 0
#define PWM_CDTY_CDTY_Msk (0xffffffu << PWM_CDTY_CDTY_Pos) /**< \brief (PWM_CDTY) Channel Duty-Cycle */
#define PWM_CDTY_CDTY(value) ((PWM_CDTY_CDTY_Msk & ((value) << PWM_CDTY_CDTY_Pos)))
/* -------- PWM_CDTYUPD : (PWM Offset: N/A) PWM Channel Duty Cycle Update Register -------- */
#define PWM_CDTYUPD_CDTYUPD_Pos 0
#define PWM_CDTYUPD_CDTYUPD_Msk (0xffffffu << PWM_CDTYUPD_CDTYUPD_Pos) /**< \brief (PWM_CDTYUPD) Channel Duty-Cycle Update */
#define PWM_CDTYUPD_CDTYUPD(value) ((PWM_CDTYUPD_CDTYUPD_Msk & ((value) << PWM_CDTYUPD_CDTYUPD_Pos)))
/* -------- PWM_CPRD : (PWM Offset: N/A) PWM Channel Period Register -------- */
#define PWM_CPRD_CPRD_Pos 0
#define PWM_CPRD_CPRD_Msk (0xffffffu << PWM_CPRD_CPRD_Pos) /**< \brief (PWM_CPRD) Channel Period */
#define PWM_CPRD_CPRD(value) ((PWM_CPRD_CPRD_Msk & ((value) << PWM_CPRD_CPRD_Pos)))
/* -------- PWM_CPRDUPD : (PWM Offset: N/A) PWM Channel Period Update Register -------- */
#define PWM_CPRDUPD_CPRDUPD_Pos 0
#define PWM_CPRDUPD_CPRDUPD_Msk (0xffffffu << PWM_CPRDUPD_CPRDUPD_Pos) /**< \brief (PWM_CPRDUPD) Channel Period Update */
#define PWM_CPRDUPD_CPRDUPD(value) ((PWM_CPRDUPD_CPRDUPD_Msk & ((value) << PWM_CPRDUPD_CPRDUPD_Pos)))
/* -------- PWM_CCNT : (PWM Offset: N/A) PWM Channel Counter Register -------- */
#define PWM_CCNT_CNT_Pos 0
#define PWM_CCNT_CNT_Msk (0xffffffu << PWM_CCNT_CNT_Pos) /**< \brief (PWM_CCNT) Channel Counter Register */
/* -------- PWM_DT : (PWM Offset: N/A) PWM Channel Dead Time Register -------- */
#define PWM_DT_DTH_Pos 0
#define PWM_DT_DTH_Msk (0xffffu << PWM_DT_DTH_Pos) /**< \brief (PWM_DT) Dead-Time Value for PWMHx Output */
#define PWM_DT_DTH(value) ((PWM_DT_DTH_Msk & ((value) << PWM_DT_DTH_Pos)))
#define PWM_DT_DTL_Pos 16
#define PWM_DT_DTL_Msk (0xffffu << PWM_DT_DTL_Pos) /**< \brief (PWM_DT) Dead-Time Value for PWMLx Output */
#define PWM_DT_DTL(value) ((PWM_DT_DTL_Msk & ((value) << PWM_DT_DTL_Pos)))
/* -------- PWM_DTUPD : (PWM Offset: N/A) PWM Channel Dead Time Update Register -------- */
#define PWM_DTUPD_DTHUPD_Pos 0
#define PWM_DTUPD_DTHUPD_Msk (0xffffu << PWM_DTUPD_DTHUPD_Pos) /**< \brief (PWM_DTUPD) Dead-Time Value Update for PWMHx Output */
#define PWM_DTUPD_DTHUPD(value) ((PWM_DTUPD_DTHUPD_Msk & ((value) << PWM_DTUPD_DTHUPD_Pos)))
#define PWM_DTUPD_DTLUPD_Pos 16
#define PWM_DTUPD_DTLUPD_Msk (0xffffu << PWM_DTUPD_DTLUPD_Pos) /**< \brief (PWM_DTUPD) Dead-Time Value Update for PWMLx Output */
#define PWM_DTUPD_DTLUPD(value) ((PWM_DTUPD_DTLUPD_Msk & ((value) << PWM_DTUPD_DTLUPD_Pos)))
/*@}*/
#endif /* _SAM3XA_PWM_COMPONENT_ */

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