|
1 | 1 | import struct |
2 | 2 | from enum import Enum |
3 | | -from typing import TYPE_CHECKING, Tuple |
| 3 | +from typing import TYPE_CHECKING |
4 | 4 | import logging |
5 | 5 |
|
6 | 6 | from durand.datatypes import DatatypeEnum as DT |
@@ -32,6 +32,7 @@ class SDOServer: |
32 | 32 | def __init__(self, node: "Node", index=0): |
33 | 33 | self._node = node |
34 | 34 | self._index = index |
| 35 | + self._stopped = True |
35 | 36 |
|
36 | 37 | from .download import DownloadManager |
37 | 38 | from .upload import UploadManager |
@@ -84,28 +85,41 @@ def __init__(self, node: "Node", index=0): |
84 | 85 | 2: self.upload_manager.init_upload, |
85 | 86 | 3: self.upload_manager.upload_segment, |
86 | 87 | 5: self.upload_manager.init_upload, |
87 | | - 6: self._handle_download_block |
| 88 | + 6: self._handle_download_block, |
88 | 89 | } |
89 | 90 |
|
90 | 91 | @property |
91 | 92 | def node(self): |
92 | 93 | return self._node |
93 | 94 |
|
94 | 95 | def _update_subscription(self, state: StateEnum): |
95 | | - if state == StateEnum.STOPPED: |
| 96 | + if not self._stopped and state == StateEnum.STOPPED: |
96 | 97 | self._node.network.remove_subscription(self._cob_rx) |
97 | | - elif state == StateEnum.PRE_OPERATIONAL and not ( |
98 | | - self._cob_rx | self._cob_tx |
99 | | - ) & (1 << 31): |
| 98 | + self._stopped = True |
| 99 | + return |
| 100 | + |
| 101 | + if ( |
| 102 | + self._stopped |
| 103 | + and state in (StateEnum.PRE_OPERATIONAL, StateEnum.OPERATIONAL) |
| 104 | + and not (self._cob_rx | self._cob_tx) & (1 << 31) |
| 105 | + ): |
100 | 106 | self._node.network.add_subscription(self._cob_rx, self.handle_msg) |
| 107 | + self._stopped = False |
101 | 108 |
|
102 | 109 | def _update_node(self, state: StateEnum): |
103 | | - if state == StateEnum.STOPPED: |
| 110 | + if not self._stopped and state == StateEnum.STOPPED: |
104 | 111 | self._node.network.remove_subscription(self._cob_rx) |
105 | | - elif state == StateEnum.PRE_OPERATIONAL: |
| 112 | + self._stopped = True |
| 113 | + return |
| 114 | + |
| 115 | + if self._stopped and state in ( |
| 116 | + StateEnum.PRE_OPERATIONAL, |
| 117 | + StateEnum.OPERATIONAL, |
| 118 | + ): |
106 | 119 | self._cob_rx = 0x600 + self._node.node_id |
107 | 120 | self._cob_tx = 0x580 + self._node.node_id |
108 | 121 | self._node.network.add_subscription(self._cob_rx, self.handle_msg) |
| 122 | + self._stopped = False |
109 | 123 |
|
110 | 124 | def _update_cob_rx(self, value: int): |
111 | 125 | # bit 31: 0 - valid, 1 - invalid |
@@ -182,7 +196,7 @@ def handle_msg(self, cob_id: int, msg: bytes) -> None: |
182 | 196 | try: |
183 | 197 | return self._handle_cs_dict[ccs](msg) |
184 | 198 | except KeyError as exc: # ccs not found |
185 | | - raise SDODomainAbort(0x05040001) from exc # SDO command not implemented |
| 199 | + raise SDODomainAbort(0x05040001) from exc # SDO command not implemented |
186 | 200 | except SDODomainAbort as exc: |
187 | 201 | index, subindex = 0, 0 |
188 | 202 | if exc.multiplexor: |
|
0 commit comments