47 |
47 |
48 /** Constructor. |
48 /** Constructor. |
49 */ |
49 */ |
50 void ec_sync_init( |
50 void ec_sync_init( |
51 ec_sync_t *sync, /**< EtherCAT sync manager. */ |
51 ec_sync_t *sync, /**< EtherCAT sync manager. */ |
52 ec_slave_t *slave, /**< EtherCAT slave. */ |
52 ec_slave_t *slave /**< EtherCAT slave. */ |
53 unsigned int index /**< Sync manager index. */ |
|
54 ) |
53 ) |
55 { |
54 { |
56 sync->slave = slave; |
55 sync->slave = slave; |
57 sync->index = index; |
56 sync->physical_start_address = 0x0000; |
58 |
57 sync->default_length = 0x0000; |
|
58 sync->control_register = 0x00; |
|
59 sync->enable = 0x00; |
59 ec_pdo_list_init(&sync->pdos); |
60 ec_pdo_list_init(&sync->pdos); |
60 sync->assign_source = EC_ASSIGN_NONE; |
61 sync->assign_source = EC_ASSIGN_NONE; |
61 } |
62 } |
62 |
63 |
63 /*****************************************************************************/ |
64 /*****************************************************************************/ |
68 ec_sync_t *sync, /**< EtherCAT sync manager. */ |
69 ec_sync_t *sync, /**< EtherCAT sync manager. */ |
69 const ec_sync_t *other /**< Sync manager to copy from. */ |
70 const ec_sync_t *other /**< Sync manager to copy from. */ |
70 ) |
71 ) |
71 { |
72 { |
72 sync->slave = other->slave; |
73 sync->slave = other->slave; |
73 sync->index = other->index; |
|
74 sync->physical_start_address = other->physical_start_address; |
74 sync->physical_start_address = other->physical_start_address; |
75 sync->length = other->length; |
75 sync->default_length = other->default_length; |
76 sync->control_register = other->control_register; |
76 sync->control_register = other->control_register; |
77 sync->enable = other->enable; |
77 sync->enable = other->enable; |
78 |
|
79 ec_pdo_list_init(&sync->pdos); |
78 ec_pdo_list_init(&sync->pdos); |
80 ec_pdo_list_copy(&sync->pdos, &other->pdos); |
79 ec_pdo_list_copy(&sync->pdos, &other->pdos); |
81 |
|
82 sync->assign_source = other->assign_source; |
80 sync->assign_source = other->assign_source; |
83 } |
81 } |
84 |
82 |
85 /*****************************************************************************/ |
83 /*****************************************************************************/ |
86 |
84 |
93 ec_pdo_list_clear(&sync->pdos); |
91 ec_pdo_list_clear(&sync->pdos); |
94 } |
92 } |
95 |
93 |
96 /*****************************************************************************/ |
94 /*****************************************************************************/ |
97 |
95 |
98 /** Initializes a sync manager configuration page with SII data. |
96 /** Initializes a sync manager configuration page. |
99 * |
97 * |
100 * The referenced memory (\a data) must be at least \a EC_SYNC_SIZE bytes. |
98 * The referenced memory (\a data) must be at least \a EC_SYNC_SIZE bytes. |
101 */ |
99 */ |
102 void ec_sync_config( |
100 void ec_sync_page( |
103 const ec_sync_t *sync, /**< Sync manager. */ |
101 const ec_sync_t *sync, /**< Sync manager. */ |
|
102 uint8_t sync_index, /**< Index of the sync manager. */ |
104 uint16_t data_size, /**< Data size. */ |
103 uint16_t data_size, /**< Data size. */ |
|
104 ec_direction_t dir, /**< Direction (overrides the control byte, |
|
105 if set to EC_DIR_INPUT or EC_DIR_OUTPUT). */ |
105 uint8_t *data /**> Configuration memory. */ |
106 uint8_t *data /**> Configuration memory. */ |
106 ) |
107 ) |
107 { |
108 { |
108 // enable only if SII enable is set and size is > 0. |
109 // enable only if SII enable is set and size is > 0. |
109 uint16_t enable = sync->enable && data_size; |
110 uint16_t enable = sync->enable && data_size; |
|
111 uint8_t control = sync->control_register; |
110 |
112 |
111 if (sync->slave->master->debug_level) { |
113 if (dir == EC_DIR_OUTPUT || dir == EC_DIR_INPUT) { |
|
114 // override sync manager direction bits with dir parameter |
|
115 EC_WRITE_BIT(&control, 2, dir == EC_DIR_OUTPUT ? 1 : 0); |
|
116 EC_WRITE_BIT(&control, 3, 0); |
|
117 } |
|
118 |
|
119 if (sync->slave->master->debug_level) |
112 EC_DBG("SM%u: Addr 0x%04X, Size %3u, Ctrl 0x%02X, En %u\n", |
120 EC_DBG("SM%u: Addr 0x%04X, Size %3u, Ctrl 0x%02X, En %u\n", |
113 sync->index, sync->physical_start_address, |
121 sync_index, sync->physical_start_address, |
114 data_size, sync->control_register, enable); |
122 data_size, control, enable); |
115 } |
|
116 |
123 |
117 EC_WRITE_U16(data, sync->physical_start_address); |
124 EC_WRITE_U16(data, sync->physical_start_address); |
118 EC_WRITE_U16(data + 2, data_size); |
125 EC_WRITE_U16(data + 2, data_size); |
119 EC_WRITE_U8 (data + 4, sync->control_register); |
126 EC_WRITE_U8 (data + 4, control); |
120 EC_WRITE_U8 (data + 5, 0x00); // status byte (read only) |
127 EC_WRITE_U8 (data + 5, 0x00); // status byte (read only) |
121 EC_WRITE_U16(data + 6, enable); |
128 EC_WRITE_U16(data + 6, enable); |
122 } |
129 } |
123 |
130 |
124 /*****************************************************************************/ |
131 /*****************************************************************************/ |
135 return ec_pdo_list_add_pdo_copy(&sync->pdos, pdo); |
142 return ec_pdo_list_add_pdo_copy(&sync->pdos, pdo); |
136 } |
143 } |
137 |
144 |
138 /*****************************************************************************/ |
145 /*****************************************************************************/ |
139 |
146 |
140 /** Get direction covered by sync manager. |
147 /** Determines the default direction from the control register. |
141 * |
|
142 * \return Direction covered by the given sync manager. |
|
143 */ |
148 */ |
144 ec_direction_t ec_sync_direction( |
149 ec_direction_t ec_sync_default_direction( |
145 const ec_sync_t *sync /**< EtherCAT sync manager. */ |
150 const ec_sync_t *sync /**< EtherCAT sync manager. */ |
146 ) |
151 ) |
147 { |
152 { |
148 int index = sync->index; |
153 switch ((sync->control_register & 0x0C) >> 2) { |
149 |
154 case 0x0: return EC_DIR_INPUT; |
150 if (sync->slave->sii.sync_count != 1) { |
155 case 0x1: return EC_DIR_INPUT; |
151 if (sync->slave && sync->slave->sii.mailbox_protocols) { |
156 default: return EC_DIR_INVALID; |
152 index -= 2; |
|
153 } |
|
154 |
|
155 if (index < 0 || index > 1) { |
|
156 EC_WARN("ec_sync_get_direction(): invalid sync manager index.\n"); |
|
157 return EC_DIR_OUTPUT; |
|
158 } |
|
159 } else { // sync_count == 1 |
|
160 if (!list_empty(&sync->pdos.list)) { |
|
161 const ec_pdo_t *pdo = |
|
162 list_entry(sync->pdos.list.next, ec_pdo_t, list); |
|
163 return pdo->dir; |
|
164 } |
|
165 |
|
166 } |
157 } |
167 |
|
168 return (ec_direction_t) index; |
|
169 } |
158 } |
170 |
159 |
171 /*****************************************************************************/ |
160 /*****************************************************************************/ |