Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
E
etherlabmaster
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Jira
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ICS Control System Infrastructure
etherlabmaster
Commits
6c50ff6e
Commit
6c50ff6e
authored
17 years ago
by
Florian Pose
Browse files
Options
Downloads
Patches
Plain Diff
SII writing workaround for some slaves, that don't respond correctly;
improved SII code.
parent
6938a05a
No related branches found
No related tags found
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
NEWS
+2
-0
2 additions, 0 deletions
NEWS
TODO
+4
-3
4 additions, 3 deletions
TODO
master/fsm_sii.c
+75
-42
75 additions, 42 deletions
master/fsm_sii.c
master/fsm_sii.h
+1
-1
1 addition, 1 deletion
master/fsm_sii.h
with
82 additions
and
46 deletions
NEWS
+
2
−
0
View file @
6c50ff6e
...
@@ -6,6 +6,8 @@ $Id$
...
@@ -6,6 +6,8 @@ $Id$
Changes in version 1.3.2:
Changes in version 1.3.2:
* Implemented SII writing workaround for some slaves, that don't respond
correctly.
* Read dynamic PDO mapping from SDO dictionary.
* Read dynamic PDO mapping from SDO dictionary.
* Improved handling for spontaneous AL state changes.
* Improved handling for spontaneous AL state changes.
* Master takes mailbox sync manager configurations from EEPROM words
* Master takes mailbox sync manager configurations from EEPROM words
...
...
This diff is collapsed.
Click to expand it.
TODO
+
4
−
3
View file @
6c50ff6e
...
@@ -7,15 +7,16 @@ $Id$
...
@@ -7,15 +7,16 @@ $Id$
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
* Future features:
* Future features:
- Interface/buffers for asynchronous domain IO.
- Distributed clocks.
- Distributed clocks.
- Redundancy with 2 network adapters.
- Redundancy with 2 network adapters.
- Mailbox handler
- Mailbox handler
- Support slaves, that don't support the LRW datagram, only LRD/LWR.
- Support slaves, that don't support the LRW datagram, only LRD/LWR.
- PDO reading in IDLE mode.
- PDO reading in IDLE mode.
- Replace Sysfs interface with cdev and user space program.
- Replace Sysfs interface with cdev and user space program.
- Interface/buffers for asynchronous domain IO.
* Smaller issues:
* Smaller issues:
- Datagram debugging flag.
- Clear sync managers in INIT.
- Clear sync managers in INIT.
- Simplify FSMs with <state>_enter() functions.
- Simplify FSMs with <state>_enter() functions.
- Output intermediate results during lsec.
- Output intermediate results during lsec.
...
@@ -30,12 +31,12 @@ $Id$
...
@@ -30,12 +31,12 @@ $Id$
- Interrupt master state machines state scan for other jobs.
- Interrupt master state machines state scan for other jobs.
- Master state machine, slave configuration: Do not check every slave on
- Master state machine, slave configuration: Do not check every slave on
a cycle.
a cycle.
-
Do o
nly execute one EoE handler per EoE cycle.
-
O
nly execute one EoE handler per EoE cycle.
* Less important issues:
* Less important issues:
- Implement all EtherCAT datagram types.
- Implement all EtherCAT datagram types.
- File access over EtherCAT (FoE).
- File access over EtherCAT (FoE).
- Allow VLAN tagging.
- Allow VLAN tagging.
- Determine number of frames the NIC can handle.
- Determine number of frames
,
the NIC can handle.
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
This diff is collapsed.
Click to expand it.
master/fsm_sii.c
+
75
−
42
View file @
6c50ff6e
...
@@ -43,6 +43,11 @@
...
@@ -43,6 +43,11 @@
#include
"master.h"
#include
"master.h"
#include
"fsm_sii.h"
#include
"fsm_sii.h"
#define EEPROM_TIMEOUT 10 // read/write timeout [ms]
#define EEPROM_INHIBIT 5 // time before evaluating answer at writing [ms]
//#define SII_DEBUG
/*****************************************************************************/
/*****************************************************************************/
void
ec_fsm_sii_state_start_reading
(
ec_fsm_sii_t
*
);
void
ec_fsm_sii_state_start_reading
(
ec_fsm_sii_t
*
);
...
@@ -86,13 +91,13 @@ void ec_fsm_sii_clear(ec_fsm_sii_t *fsm /**< finite state machine */)
...
@@ -86,13 +91,13 @@ void ec_fsm_sii_clear(ec_fsm_sii_t *fsm /**< finite state machine */)
void
ec_fsm_sii_read
(
ec_fsm_sii_t
*
fsm
,
/**< finite state machine */
void
ec_fsm_sii_read
(
ec_fsm_sii_t
*
fsm
,
/**< finite state machine */
ec_slave_t
*
slave
,
/**< slave to read from */
ec_slave_t
*
slave
,
/**< slave to read from */
uint16_t
offset
,
/**< offset to read from */
uint16_t
word_
offset
,
/**< offset to read from */
ec_fsm_sii_addressing_t
mode
/**< addressing scheme */
ec_fsm_sii_addressing_t
mode
/**< addressing scheme */
)
)
{
{
fsm
->
state
=
ec_fsm_sii_state_start_reading
;
fsm
->
state
=
ec_fsm_sii_state_start_reading
;
fsm
->
slave
=
slave
;
fsm
->
slave
=
slave
;
fsm
->
offset
=
offset
;
fsm
->
word_
offset
=
word_
offset
;
fsm
->
mode
=
mode
;
fsm
->
mode
=
mode
;
}
}
...
@@ -104,14 +109,14 @@ void ec_fsm_sii_read(ec_fsm_sii_t *fsm, /**< finite state machine */
...
@@ -104,14 +109,14 @@ void ec_fsm_sii_read(ec_fsm_sii_t *fsm, /**< finite state machine */
void
ec_fsm_sii_write
(
ec_fsm_sii_t
*
fsm
,
/**< finite state machine */
void
ec_fsm_sii_write
(
ec_fsm_sii_t
*
fsm
,
/**< finite state machine */
ec_slave_t
*
slave
,
/**< slave to read from */
ec_slave_t
*
slave
,
/**< slave to read from */
uint16_t
offset
,
/**< offset to read from */
uint16_t
word_
offset
,
/**< offset to read from */
const
uint8_t
*
value
,
/**< pointer to 2 bytes of data */
const
uint8_t
*
value
,
/**< pointer to 2 bytes of data */
ec_fsm_sii_addressing_t
mode
/**< addressing scheme */
ec_fsm_sii_addressing_t
mode
/**< addressing scheme */
)
)
{
{
fsm
->
state
=
ec_fsm_sii_state_start_writing
;
fsm
->
state
=
ec_fsm_sii_state_start_writing
;
fsm
->
slave
=
slave
;
fsm
->
slave
=
slave
;
fsm
->
offset
=
offset
;
fsm
->
word_
offset
=
word_
offset
;
fsm
->
mode
=
mode
;
fsm
->
mode
=
mode
;
memcpy
(
fsm
->
value
,
value
,
2
);
memcpy
(
fsm
->
value
,
value
,
2
);
}
}
...
@@ -168,9 +173,15 @@ void ec_fsm_sii_state_start_reading(
...
@@ -168,9 +173,15 @@ void ec_fsm_sii_state_start_reading(
break
;
break
;
}
}
EC_WRITE_U8
(
datagram
->
data
,
0x
0
0
);
//
read-only acces
s
EC_WRITE_U8
(
datagram
->
data
,
0x
8
0
);
//
two address octet
s
EC_WRITE_U8
(
datagram
->
data
+
1
,
0x01
);
// request read operation
EC_WRITE_U8
(
datagram
->
data
+
1
,
0x01
);
// request read operation
EC_WRITE_U16
(
datagram
->
data
+
2
,
fsm
->
offset
);
EC_WRITE_U16
(
datagram
->
data
+
2
,
fsm
->
word_offset
);
#ifdef SII_DEBUG
EC_DBG
(
"reading SII data:
\n
"
);
ec_print_data
(
datagram
->
data
,
4
);
#endif
fsm
->
retries
=
EC_FSM_RETRIES
;
fsm
->
retries
=
EC_FSM_RETRIES
;
fsm
->
state
=
ec_fsm_sii_state_read_check
;
fsm
->
state
=
ec_fsm_sii_state_read_check
;
}
}
...
@@ -256,47 +267,37 @@ void ec_fsm_sii_state_read_fetch(
...
@@ -256,47 +267,37 @@ void ec_fsm_sii_state_read_fetch(
return
;
return
;
}
}
#ifdef SII_DEBUG
EC_DBG
(
"checking SII read state:
\n
"
);
ec_print_data
(
datagram
->
data
,
10
);
#endif
if
(
EC_READ_U8
(
datagram
->
data
+
1
)
&
0x20
)
{
EC_ERR
(
"SII: Error on last SII command!
\n
"
);
fsm
->
state
=
ec_fsm_sii_state_error
;
return
;
}
// check "busy bit"
// check "busy bit"
if
(
EC_READ_U8
(
datagram
->
data
+
1
)
&
0x81
)
{
if
(
EC_READ_U8
(
datagram
->
data
+
1
)
&
0x81
)
{
// busy bit or
// read operation busy
// still busy... timeout?
// still busy... timeout?
if
(
datagram
->
cycles_received
if
(
datagram
->
cycles_received
-
fsm
->
cycles_start
>=
(
cycles_t
)
10
*
cpu_khz
)
{
-
fsm
->
cycles_start
>=
(
cycles_t
)
EEPROM_TIMEOUT
*
cpu_khz
)
{
if
(
!
fsm
->
check_once_more
)
{
if
(
fsm
->
check_once_more
)
{
fsm
->
check_once_more
=
0
;
}
else
{
EC_ERR
(
"SII: Read timeout.
\n
"
);
EC_ERR
(
"SII: Read timeout.
\n
"
);
fsm
->
state
=
ec_fsm_sii_state_error
;
fsm
->
state
=
ec_fsm_sii_state_error
;
#if 0
EC_DBG("SII busy: %02X %02X %02X %02X\n",
EC_READ_U8(datagram->data + 0),
EC_READ_U8(datagram->data + 1),
EC_READ_U8(datagram->data + 2),
EC_READ_U8(datagram->data + 3));
#endif
return
;
return
;
}
}
fsm
->
check_once_more
=
0
;
}
}
// issue check/fetch datagram again
// issue check/fetch datagram again
switch
(
fsm
->
mode
)
{
case
EC_FSM_SII_POSITION
:
ec_datagram_aprd
(
datagram
,
fsm
->
slave
->
ring_position
,
0x502
,
10
);
break
;
case
EC_FSM_SII_NODE
:
ec_datagram_nprd
(
datagram
,
fsm
->
slave
->
station_address
,
0x502
,
10
);
break
;
}
fsm
->
retries
=
EC_FSM_RETRIES
;
fsm
->
retries
=
EC_FSM_RETRIES
;
return
;
return
;
}
}
#if 0
EC_DBG("SII rec: %02X %02X %02X %02X - %02X %02X %02X %02X\n",
EC_READ_U8(datagram->data + 0), EC_READ_U8(datagram->data + 1),
EC_READ_U8(datagram->data + 2), EC_READ_U8(datagram->data + 3),
EC_READ_U8(datagram->data + 6), EC_READ_U8(datagram->data + 7),
EC_READ_U8(datagram->data + 8), EC_READ_U8(datagram->data + 9));
#endif
// SII value received.
// SII value received.
memcpy
(
fsm
->
value
,
datagram
->
data
+
6
,
4
);
memcpy
(
fsm
->
value
,
datagram
->
data
+
6
,
4
);
fsm
->
state
=
ec_fsm_sii_state_end
;
fsm
->
state
=
ec_fsm_sii_state_end
;
...
@@ -306,7 +307,7 @@ void ec_fsm_sii_state_read_fetch(
...
@@ -306,7 +307,7 @@ void ec_fsm_sii_state_read_fetch(
/**
/**
SII state: START WRITING.
SII state: START WRITING.
Starts
reading
the slave information interface.
Starts
writing a word through
the slave information interface.
*/
*/
void
ec_fsm_sii_state_start_writing
(
void
ec_fsm_sii_state_start_writing
(
...
@@ -317,11 +318,18 @@ void ec_fsm_sii_state_start_writing(
...
@@ -317,11 +318,18 @@ void ec_fsm_sii_state_start_writing(
// initiate write operation
// initiate write operation
ec_datagram_npwr
(
datagram
,
fsm
->
slave
->
station_address
,
0x502
,
8
);
ec_datagram_npwr
(
datagram
,
fsm
->
slave
->
station_address
,
0x502
,
8
);
EC_WRITE_U8
(
datagram
->
data
,
0x01
);
// enable write access
EC_WRITE_U8
(
datagram
->
data
,
0x81
);
// two address octets
// + enable write access
EC_WRITE_U8
(
datagram
->
data
+
1
,
0x02
);
// request write operation
EC_WRITE_U8
(
datagram
->
data
+
1
,
0x02
);
// request write operation
EC_WRITE_U32
(
datagram
->
data
+
2
,
fsm
->
offset
);
EC_WRITE_U16
(
datagram
->
data
+
2
,
fsm
->
word_offset
);
memset
(
datagram
->
data
+
4
,
0x00
,
2
);
memcpy
(
datagram
->
data
+
6
,
fsm
->
value
,
2
);
memcpy
(
datagram
->
data
+
6
,
fsm
->
value
,
2
);
#ifdef SII_DEBUG
EC_DBG
(
"writing SII data:
\n
"
);
ec_print_data
(
datagram
->
data
,
8
);
#endif
fsm
->
retries
=
EC_FSM_RETRIES
;
fsm
->
retries
=
EC_FSM_RETRIES
;
fsm
->
state
=
ec_fsm_sii_state_write_check
;
fsm
->
state
=
ec_fsm_sii_state_write_check
;
}
}
...
@@ -360,7 +368,7 @@ void ec_fsm_sii_state_write_check(
...
@@ -360,7 +368,7 @@ void ec_fsm_sii_state_write_check(
fsm
->
cycles_start
=
datagram
->
cycles_sent
;
fsm
->
cycles_start
=
datagram
->
cycles_sent
;
fsm
->
check_once_more
=
1
;
fsm
->
check_once_more
=
1
;
// issue check
/fetch
datagram
// issue check datagram
ec_datagram_nprd
(
datagram
,
fsm
->
slave
->
station_address
,
0x502
,
2
);
ec_datagram_nprd
(
datagram
,
fsm
->
slave
->
station_address
,
0x502
,
2
);
fsm
->
retries
=
EC_FSM_RETRIES
;
fsm
->
retries
=
EC_FSM_RETRIES
;
fsm
->
state
=
ec_fsm_sii_state_write_check2
;
fsm
->
state
=
ec_fsm_sii_state_write_check2
;
...
@@ -397,19 +405,44 @@ void ec_fsm_sii_state_write_check2(
...
@@ -397,19 +405,44 @@ void ec_fsm_sii_state_write_check2(
return
;
return
;
}
}
if
(
EC_READ_U8
(
datagram
->
data
+
1
)
&
0x82
)
{
#ifdef SII_DEBUG
EC_DBG
(
"checking SII write state:
\n
"
);
ec_print_data
(
datagram
->
data
,
2
);
#endif
if
(
EC_READ_U8
(
datagram
->
data
+
1
)
&
0x20
)
{
EC_ERR
(
"SII: Error on last SII command!
\n
"
);
fsm
->
state
=
ec_fsm_sii_state_error
;
return
;
}
/* FIXME: some slaves never answer with the busy flag set...
* wait a few ms for the write operation to complete. */
if
(
datagram
->
cycles_received
-
fsm
->
cycles_start
<
(
cycles_t
)
EEPROM_INHIBIT
*
cpu_khz
)
{
#ifdef SII_DEBUG
EC_DBG
(
"too early.
\n
"
);
#endif
// issue check datagram again
fsm
->
retries
=
EC_FSM_RETRIES
;
return
;
}
if
(
EC_READ_U8
(
datagram
->
data
+
1
)
&
0x82
)
{
// busy bit or
// write operation busy bit
// still busy... timeout?
// still busy... timeout?
if
(
datagram
->
cycles_received
if
(
datagram
->
cycles_received
-
fsm
->
cycles_start
>=
(
cycles_t
)
10
*
cpu_khz
)
{
-
fsm
->
cycles_start
>=
(
cycles_t
)
EEPROM_TIMEOUT
*
cpu_khz
)
{
if
(
!
fsm
->
check_once_more
)
{
if
(
fsm
->
check_once_more
)
{
fsm
->
check_once_more
=
0
;
}
else
{
EC_ERR
(
"SII: Write timeout.
\n
"
);
EC_ERR
(
"SII: Write timeout.
\n
"
);
fsm
->
state
=
ec_fsm_sii_state_error
;
fsm
->
state
=
ec_fsm_sii_state_error
;
return
;
return
;
}
}
fsm
->
check_once_more
=
0
;
}
}
// issue check
/fetch
datagram again
// issue check datagram again
fsm
->
retries
=
EC_FSM_RETRIES
;
fsm
->
retries
=
EC_FSM_RETRIES
;
return
;
return
;
}
}
...
...
This diff is collapsed.
Click to expand it.
master/fsm_sii.h
+
1
−
1
View file @
6c50ff6e
...
@@ -70,7 +70,7 @@ struct ec_fsm_sii
...
@@ -70,7 +70,7 @@ struct ec_fsm_sii
unsigned
int
retries
;
/**< retries upon datagram timeout */
unsigned
int
retries
;
/**< retries upon datagram timeout */
void
(
*
state
)(
ec_fsm_sii_t
*
);
/**< SII state function */
void
(
*
state
)(
ec_fsm_sii_t
*
);
/**< SII state function */
uint16_t
offset
;
/**< input: offset in SII */
uint16_t
word_
offset
;
/**< input:
word
offset in SII */
ec_fsm_sii_addressing_t
mode
;
/**< reading via APRD or NPRD */
ec_fsm_sii_addressing_t
mode
;
/**< reading via APRD or NPRD */
uint8_t
value
[
4
];
/**< raw SII value (32bit) */
uint8_t
value
[
4
];
/**< raw SII value (32bit) */
cycles_t
cycles_start
;
/**< start timestamp */
cycles_t
cycles_start
;
/**< start timestamp */
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment