diff --git a/Doxyfile b/Doxyfile
index cee7d54..4ae5f82 100644
--- a/Doxyfile
+++ b/Doxyfile
@@ -32,7 +32,7 @@ PROJECT_NAME = SOEM
# This could be handy for archiving the generated documentation or
# if some version control system is used.
-PROJECT_NUMBER = v1.3.3
+PROJECT_NUMBER = v1.4.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer
diff --git a/doc/images/legacy_iomap.png b/doc/images/legacy_iomap.png
new file mode 100644
index 0000000..1fa3914
Binary files /dev/null and b/doc/images/legacy_iomap.png differ
diff --git a/doc/images/overlapping_iomap.png b/doc/images/overlapping_iomap.png
new file mode 100644
index 0000000..b34e9cb
Binary files /dev/null and b/doc/images/overlapping_iomap.png differ
diff --git a/doc/soem.dox b/doc/soem.dox
index 4785dc9..f03da0f 100644
--- a/doc/soem.dox
+++ b/doc/soem.dox
@@ -114,6 +114,13 @@
* - Error messages updated to latest ETG1020 document.
* - FoE transfers now support busy response.
*
+ * Features as of 1.4.0 :
+ *
+ * Added ERIKA target.
+ * Added macOS target.
+ * Support for EoE over existing mailbox API.
+ *
+ *
* \section build Build instructions
*
* See README.md in the root folder.
@@ -187,6 +194,9 @@
* - Added rtems target.
* - Added support for overlapping IOmap.
*
+ * Version 1.4.0 : 2019-05
+ * - Various fixes and improvements
+ *
* \section legal Legal notice
*
* Licensed under the GNU General Public License version 2 with exceptions. See
diff --git a/doc/tutorial.txt b/doc/tutorial.txt
index f722aa8..5f9a8ed 100644
--- a/doc/tutorial.txt
+++ b/doc/tutorial.txt
@@ -5,7 +5,7 @@
The SOEM is a library that provides the user application with the means to send
and receive EtherCAT frames. It is up to the application to provide means for:
- Reading and writing process data to be sent/received by SOEM
- - Keeping local IO data synchronised with the global IOmap
+ - Keeping local IO data synchronized with the global IOmap
- Detecting errors reported by SOEM
- Managing errors reported by SOEM
@@ -150,6 +150,122 @@ handling is split into ec_send_processdata and ec_receive_processdata.
- Now we have a system up and running, all slaves are in state operational.
+\section configuration_custom Custom Configuration
+
+\subsection iomap_config PDO Assign and PDO Config
+
+Do custom configuration with PDO Assign or PDO Config. SOEM support custom configuration during start via a
+PreOP to SafeOP configuration hook. It can be done per slave and should be set before calling
+the configuration and mapping of process data, e.g. the call to ec_config_map. Setting the configuration
+hook ensure that the custom configuration will be applied when calling recover and re-configuration
+of a slave, as described below.
+
+\code
+
+int EL7031setup(uint16 slave)
+{
+ int retval;
+ uint16 u16val;
+
+ retval = 0;
+
+ /* Map velocity PDO assignment via Complete Access*/
+ uint16 map_1c12[4] = {0x0003, 0x1601, 0x1602, 0x1604};
+ uint16 map_1c13[3] = {0x0002, 0x1a01, 0x1a03};
+
+ retval += ec_SDOwrite(slave, 0x1c12, 0x00, TRUE, sizeof(map_1c12), &map_1c12, EC_TIMEOUTSAFE);
+ retval += ec_SDOwrite(slave, 0x1c13, 0x00, TRUE, sizeof(map_1c13), &map_1c13, EC_TIMEOUTSAFE);
+
+ /* set some motor parameters, just as example */
+ u16val = 1200; // max motor current in mA
+ retval += ec_SDOwrite(slave, 0x8010, 0x01, FALSE, sizeof(u16val), &u16val, EC_TIMEOUTSAFE);
+ u16val = 150; // motor coil resistance in 0.01ohm
+ retval += ec_SDOwrite(slave, 0x8010, 0x04, FALSE, sizeof(u16val), &u16val, EC_TIMEOUTSAFE);
+
+ /* set other necessary parameters as needed */
+...
+ printf("EL7031 slave %d set, retval = %d\n", slave, retval);
+ return 1;
+}
+
+void simpletest(char *ifname)
+{
+...
+ /* Detect slave beckhoff EL7031 from vendor ID and product code */
+ if((ec_slave[slc].eep_man == 0x00000002) && (ec_slave[slc].eep_id == 0x1b773052))
+ {
+ printf("Found %s at position %d\n", ec_slave[slc].name, slc);
+ /* link slave specific setup to preop->safeop hook */
+ ec_slave[slc].PO2SOconfig = EL7031setup;
+ }
+...
+\endcode
+
+\subsection iomap_layout Legacy versus overlapping IOmap
+
+IOmap options legacy versus overlapping. Overlapping IOmap was introduced to handle
+the TI ESC that doesn't support RW access to non-interleaved input and output process
+data of multiple slaves. The difference is that legacy IOmapping will send IOmap as is
+on the EtherCAT network while the overlapping will re-use logic addressing per slave to
+replace RxPDO process data coming from the Master with TxPDO process data generated by the slave
+sent back to the master.
+
+Overview of legacy pdo map
+\image html legacy_iomap.png "Legacy IOmapping"
+\image latex legacy_iomap.png "Legacy IOmapping" width=15cm
+
+Overview of overlapping pdo map
+\image html overlapping_iomap.png "Overlapping IOmapping"
+\image latex overlapping_iomap.png "Overlapping IOmapping" width=15cm
+
+\subsection iomap_groups EtherCAT slave groups
+
+Slave groups can be used to group slaves into separate logic groups within an EtherCAT network.
+Each group will have its own logic address space mapped to an IOmap address and make it possible to
+send and receive process data at different update rate.
+
+Below is an example on how to assign a slave to a group. OBS! A slave can only be member in one group.
+
+\code
+ for (cnt = 1; cnt <= ec_slavecount; cnt++)
+ {
+ if ( )
+ {
+ ec_slave[cnt].group = ;
+ }
+ else
+ {
+ ec_slave[cnt].group = ;
+ }
+ }
+\endcode
+
+Alternative 1, configure all slave groups at once, call ec_config_map or ec_config_map_group with arg 0.
+This option will share IOmap and store the group IOmap data at offset EC_LOGGROUPOFFSET.
+
+\code
+ ec_config_map_group(&IOmap, 0);
+\endcode
+
+Alternative 2, configure the slave groups one by one, call ec_config_map or ec_config_map_group with arg , .
+This option will use different, supplied by the user, IOmaps.
+
+\code
+ ec_config_map_group(&IOmap1, );
+ ec_config_map_group(&IOmap2, );
+\endcode
+
+To exchange process data for given group(s) the user must call send/recv process data per group.
+The send and receive stack of process data don't consider groups, so the application has to send
+and receive the process data for one group before sending/receiving process data for another group.
+
+\code
+ ec_send_processdata_group();
+ ec_receive_processdata_group(, EC_TIMEOUTRET);
+ ec_send_processdata_group();
+ ec_receive_processdata_group(, EC_TIMEOUTRET);
+\endcode
+
\section application Application
\subsection iomap Accessing data through IOmap