master/sync.c
changeset 1055 2be8918682fa
parent 943 1d9e2663e087
child 1060 5e51425da89f
equal deleted inserted replaced
1054:4c16fe64b403 1055:2be8918682fa
    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 /*****************************************************************************/