drivers/ec_master.c
changeset 2 b0a7a4745bf9
parent 0 05c992bf5847
child 5 6f2508af550c
equal deleted inserted replaced
1:98acc19c7594 2:b0a7a4745bf9
    53   master->command_index = 0x00;
    53   master->command_index = 0x00;
    54   master->tx_data_length = 0;
    54   master->tx_data_length = 0;
    55   master->process_data = NULL;
    55   master->process_data = NULL;
    56   master->process_data_length = 0;
    56   master->process_data_length = 0;
    57   master->cmd_ring_index = 0;
    57   master->cmd_ring_index = 0;
       
    58   master->debug_level = 0;
    58 
    59 
    59   for (i = 0; i < ECAT_COMMAND_RING_SIZE; i++)
    60   for (i = 0; i < ECAT_COMMAND_RING_SIZE; i++)
    60   {
    61   {
    61     EtherCAT_command_init(&master->cmd_ring[i]);
    62     EtherCAT_command_init(&master->cmd_ring[i]);
       
    63     master->cmd_reserved[i] = 0;
    62   }
    64   }
    63 
    65 
    64   return 0;
    66   return 0;
    65 }
    67 }
    66 
    68 
    75    @param master Zeiger auf den zu löschenden Master
    77    @param master Zeiger auf den zu löschenden Master
    76 */
    78 */
    77 
    79 
    78 void EtherCAT_master_clear(EtherCAT_master_t *master)
    80 void EtherCAT_master_clear(EtherCAT_master_t *master)
    79 {
    81 {
    80   EC_DBG("Master clear");
       
    81 
       
    82   // Remove all pending commands
    82   // Remove all pending commands
    83   while (master->first_command)
    83   while (master->first_command)
    84   {
    84   {
    85     EtherCAT_remove_command(master, master->first_command);
    85     EtherCAT_remove_command(master, master->first_command);
    86   }
    86   }
    93     kfree(master->process_data);
    93     kfree(master->process_data);
    94     master->process_data = NULL;
    94     master->process_data = NULL;
    95   }
    95   }
    96 
    96 
    97   master->process_data_length = 0;
    97   master->process_data_length = 0;
    98 
       
    99   EC_DBG("done...\n");
       
   100 }
    98 }
   101 
    99 
   102 /***************************************************************/
   100 /***************************************************************/
   103 
   101 
   104 /**
   102 /**
   462   unsigned int wait_cycles;
   460   unsigned int wait_cycles;
   463   int i;
   461   int i;
   464   
   462   
   465   // Send all commands
   463   // Send all commands
   466 
   464 
   467   //EC_DBG("Master async send");
       
   468 
       
   469   for (i = 0; i < ECAT_NUM_RETRIES; i++)
   465   for (i = 0; i < ECAT_NUM_RETRIES; i++)
   470   {
   466   {
   471     ASYNC = 1;
   467     ASYNC = 1;
   472     if (EtherCAT_send(master) < 0) return -1;
   468     if (EtherCAT_send(master) < 0)
       
   469     {
       
   470       return -1;
       
   471     }
   473     ASYNC = 0;
   472     ASYNC = 0;
   474 
   473 
   475     // Wait until something is received or an error has occurred
   474     // Wait until something is received or an error has occurred
   476     wait_cycles = 10;
   475     wait_cycles = 10;
   477     while (master->dev->state == ECAT_DS_SENT && wait_cycles)
   476     while (master->dev->state == ECAT_DS_SENT && wait_cycles)
   527 {
   526 {
   528   unsigned int i, length, framelength, pos;
   527   unsigned int i, length, framelength, pos;
   529   EtherCAT_command_t *cmd;
   528   EtherCAT_command_t *cmd;
   530   int cmdcnt = 0;
   529   int cmdcnt = 0;
   531 
   530 
       
   531   if (master->debug_level > 0)
       
   532   {
       
   533     EC_DBG(KERN_DEBUG "EtherCAT_send, first_command = %X\n", (int) master->first_command);
       
   534   }
       
   535 
   532   length = 0;
   536   length = 0;
   533   for (cmd = master->first_command; cmd != NULL; cmd = cmd->next)
   537   for (cmd = master->first_command; cmd != NULL; cmd = cmd->next)
   534   {
   538   {
   535     if (cmd->state != ECAT_CS_READY) continue;
   539     if (cmd->state != ECAT_CS_READY) continue;
   536     length += cmd->data_length + 12;
   540     length += cmd->data_length + 12;
   537     cmdcnt++;
   541     cmdcnt++;
   538   }
   542   }
   539 
   543 
       
   544   if (master->debug_level > 0)
       
   545   {
       
   546     EC_DBG(KERN_DEBUG "%i commands to send.\n", cmdcnt);
       
   547   }
       
   548 
   540   if (length == 0)
   549   if (length == 0)
   541   {
   550   {
   542     EC_DBG(KERN_WARNING "EtherCAT: Nothing to send...\n");
   551     EC_DBG(KERN_WARNING "EtherCAT: Nothing to send...\n");
   543     return 0;
   552     return 0;
   544   }
   553   }
   545 
   554 
   546   framelength = length + 2;
   555   framelength = length + 2;
   547   if (framelength < 46) framelength = 46;
   556   if (framelength < 46) framelength = 46;
   548 
   557 
   549   if (ASYNC && framelength > 46)
   558   if (master->debug_level > 0)
   550     EC_DBG(KERN_WARNING "Framelength: %d", framelength);
   559   {
   551 
   560     EC_DBG(KERN_DEBUG "framelength: %i\n", framelength);
   552   if (ASYNC && cmdcnt > 1)
   561   }
   553     EC_DBG(KERN_WARNING "CMDcount: %d", cmdcnt);
       
   554 
   562 
   555   master->tx_data[0] = length & 0xFF;
   563   master->tx_data[0] = length & 0xFF;
   556   master->tx_data[1] = ((length & 0x700) >> 8) | 0x10;
   564   master->tx_data[1] = ((length & 0x700) >> 8) | 0x10;
   557   pos = 2;
   565   pos = 2;
   558 
   566 
   560   {
   568   {
   561     if (cmd->state != ECAT_CS_READY) continue;
   569     if (cmd->state != ECAT_CS_READY) continue;
   562 
   570 
   563     cmd->index = master->command_index;
   571     cmd->index = master->command_index;
   564     master->command_index = (master->command_index + 1) % 0x0100;
   572     master->command_index = (master->command_index + 1) % 0x0100;
       
   573 
       
   574     if (master->debug_level > 0)
       
   575     {
       
   576       EC_DBG(KERN_DEBUG "Sending command index %i\n", cmd->index);
       
   577     }
   565 
   578 
   566     cmd->state = ECAT_CS_SENT;
   579     cmd->state = ECAT_CS_SENT;
   567 
   580 
   568     master->tx_data[pos + 0] = cmd->type;
   581     master->tx_data[pos + 0] = cmd->type;
   569     master->tx_data[pos + 1] = cmd->index;
   582     master->tx_data[pos + 1] = cmd->index;
   615     if ((i + 1) % 16 == 0) EC_DBG("\n" KERN_DEBUG);
   628     if ((i + 1) % 16 == 0) EC_DBG("\n" KERN_DEBUG);
   616   }
   629   }
   617   EC_DBG("\n");
   630   EC_DBG("\n");
   618   EC_DBG(KERN_DEBUG "-----------------------------------------------\n");
   631   EC_DBG(KERN_DEBUG "-----------------------------------------------\n");
   619 #endif
   632 #endif
       
   633 
       
   634   if (master->debug_level > 0)
       
   635   {
       
   636     EC_DBG(KERN_DEBUG "device send...\n");
       
   637   }
   620  
   638  
   621   // Send frame
   639   // Send frame
   622   if (EtherCAT_device_send(master->dev, master->tx_data, framelength) != 0)
   640   if (EtherCAT_device_send(master->dev, master->tx_data, framelength) != 0)
   623   {
   641   {
   624     EC_DBG(KERN_ERR "EtherCAT: Could not send!\n");
   642     EC_DBG(KERN_ERR "EtherCAT: Could not send!\n");
   629       EC_DBG("%02X ", master->tx_data[i]);      
   647       EC_DBG("%02X ", master->tx_data[i]);      
   630       if ((i + 1) % 16 == 0) EC_DBG("\n" KERN_DEBUG);
   648       if ((i + 1) % 16 == 0) EC_DBG("\n" KERN_DEBUG);
   631     }
   649     }
   632     EC_DBG("\n");
   650     EC_DBG("\n");
   633     return -1;
   651     return -1;
       
   652   }
       
   653 
       
   654   if (master->debug_level > 0)
       
   655   {
       
   656     EC_DBG(KERN_DEBUG "EtherCAT_send done.\n");
   634   }
   657   }
   635 
   658 
   636   return 0;
   659   return 0;
   637 }
   660 }
   638 
   661 
   828   EtherCAT_command_init(cmd)
   851   EtherCAT_command_init(cmd)
   829 
   852 
   830 #define ECAT_FUNC_WRITE_FOOTER \
   853 #define ECAT_FUNC_WRITE_FOOTER \
   831   cmd->data_length = length; \
   854   cmd->data_length = length; \
   832   memcpy(cmd->data, data, length); \
   855   memcpy(cmd->data, data, length); \
   833   add_command(master, cmd); \
   856   if (add_command(master, cmd) < 0) return NULL; \
   834   return cmd
   857   return cmd
   835 
   858 
   836 #define ECAT_FUNC_READ_FOOTER \
   859 #define ECAT_FUNC_READ_FOOTER \
   837   cmd->data_length = length; \
   860   cmd->data_length = length; \
   838   add_command(master, cmd); \
   861   if (add_command(master, cmd) < 0) return NULL; \
   839   return cmd
   862   return cmd
   840 
   863 
   841 /***************************************************************/
   864 /***************************************************************/
   842 
   865 
   843 /**
   866 /**
  1073   int j;
  1096   int j;
  1074 
  1097 
  1075   for (j = 0; j < ECAT_COMMAND_RING_SIZE; j++) // Einmal rum suchen
  1098   for (j = 0; j < ECAT_COMMAND_RING_SIZE; j++) // Einmal rum suchen
  1076   { 
  1099   { 
  1077     // Solange suchen, bis freies Kommando gefunden
  1100     // Solange suchen, bis freies Kommando gefunden
  1078     if (master->cmd_ring[master->cmd_ring_index].reserved == 0)
  1101     if (master->cmd_reserved[master->cmd_ring_index] == 0)
  1079     {
  1102     {
  1080       master->cmd_ring[master->cmd_ring_index].reserved = 1; // Belegen
  1103       master->cmd_reserved[master->cmd_ring_index] = 1; // Belegen
       
  1104 
       
  1105       if (master->debug_level)
       
  1106       {
       
  1107         EC_DBG(KERN_DEBUG "Allocating command %i (addr %X).\n",
       
  1108                master->cmd_ring_index,
       
  1109                (int) &master->cmd_ring[master->cmd_ring_index]);
       
  1110       }
       
  1111 
  1081       return &master->cmd_ring[master->cmd_ring_index];
  1112       return &master->cmd_ring[master->cmd_ring_index];
       
  1113     }
       
  1114 
       
  1115     if (master->debug_level)
       
  1116     {
       
  1117       EC_DBG(KERN_DEBUG "Command %i (addr %X) is reserved...\n",
       
  1118              master->cmd_ring_index,
       
  1119              (int) &master->cmd_ring[master->cmd_ring_index]);
  1082     }
  1120     }
  1083 
  1121 
  1084     master->cmd_ring_index++;
  1122     master->cmd_ring_index++;
  1085     master->cmd_ring_index %= ECAT_COMMAND_RING_SIZE;
  1123     master->cmd_ring_index %= ECAT_COMMAND_RING_SIZE;
  1086   }
  1124   }
  1097 
  1135 
  1098    @param master EtherCAT-Master
  1136    @param master EtherCAT-Master
  1099    @param cmd Zeiger auf das einzufügende Kommando
  1137    @param cmd Zeiger auf das einzufügende Kommando
  1100 */
  1138 */
  1101 
  1139 
  1102 void add_command(EtherCAT_master_t *master,
  1140 int add_command(EtherCAT_master_t *master,
  1103                  EtherCAT_command_t *cmd)
  1141                 EtherCAT_command_t *new_cmd)
  1104 {
  1142 {
  1105   EtherCAT_command_t **last_cmd;
  1143   EtherCAT_command_t *cmd, **last_cmd;
       
  1144 
       
  1145   for (cmd = master->first_command; cmd != NULL; cmd = cmd->next)
       
  1146   {
       
  1147     if (cmd == new_cmd)
       
  1148     {
       
  1149       EC_DBG(KERN_WARNING "EtherCAT: Trying to add a command"
       
  1150              " that is already in the list!\n");
       
  1151       return -1;
       
  1152     }
       
  1153   }
  1106 
  1154 
  1107   // Find the address of the last pointer in the list
  1155   // Find the address of the last pointer in the list
  1108   last_cmd = &(master->first_command);
  1156   last_cmd = &(master->first_command);
  1109   while (*last_cmd) last_cmd = &(*last_cmd)->next;
  1157   while (*last_cmd) last_cmd = &(*last_cmd)->next;
  1110 
  1158 
  1111   // Let this pointer point to the new command
  1159   // Let this pointer point to the new command
  1112   *last_cmd = cmd;
  1160   *last_cmd = new_cmd;
       
  1161 
       
  1162   return 0;
  1113 }
  1163 }
  1114 
  1164 
  1115 /***************************************************************/
  1165 /***************************************************************/
  1116 
  1166 
  1117 /**
  1167 /**
  1129 
  1179 
  1130 void EtherCAT_remove_command(EtherCAT_master_t *master,
  1180 void EtherCAT_remove_command(EtherCAT_master_t *master,
  1131                              EtherCAT_command_t *rem_cmd)
  1181                              EtherCAT_command_t *rem_cmd)
  1132 {
  1182 {
  1133   EtherCAT_command_t **last_cmd;
  1183   EtherCAT_command_t **last_cmd;
       
  1184   int i;
  1134 
  1185 
  1135   last_cmd = &master->first_command;
  1186   last_cmd = &master->first_command;
  1136   while (*last_cmd)
  1187   while (*last_cmd)
  1137   {
  1188   {
  1138     if (*last_cmd == rem_cmd)
  1189     if (*last_cmd == rem_cmd)
  1139     {
  1190     {
  1140       *last_cmd = rem_cmd->next;
  1191       *last_cmd = rem_cmd->next;
  1141 
       
  1142       EtherCAT_command_clear(rem_cmd);
  1192       EtherCAT_command_clear(rem_cmd);
  1143 
  1193 
       
  1194       // Reservierung des Kommandos aufheben
       
  1195       for (i = 0; i < ECAT_COMMAND_RING_SIZE; i++)
       
  1196       {
       
  1197         if (&master->cmd_ring[i] == rem_cmd)
       
  1198         {
       
  1199           master->cmd_reserved[i] = 0;
       
  1200           return;
       
  1201         }
       
  1202       }
       
  1203 
       
  1204       EC_DBG(KERN_WARNING "EtherCAT: Could not remove command reservation!\n");
  1144       return;
  1205       return;
  1145     }
  1206     }
  1146 
  1207 
  1147     last_cmd = &(*last_cmd)->next;
  1208     last_cmd = &(*last_cmd)->next;
  1148   }
  1209   }
  1593 {
  1654 {
  1594   unsigned int i;
  1655   unsigned int i;
  1595 
  1656 
  1596   for (i = 0; i < master->slave_count; i++)
  1657   for (i = 0; i < master->slave_count; i++)
  1597   {
  1658   {
  1598     EC_DBG("Activate Slave: %d\n",i);
       
  1599 
       
  1600     if (EtherCAT_activate_slave(master, &master->slaves[i]) < 0)
  1659     if (EtherCAT_activate_slave(master, &master->slaves[i]) < 0)
  1601     {
  1660     {
  1602       return -1;
  1661       return -1;
  1603     }
  1662     }
  1604 
       
  1605     EC_DBG("done...\n");
       
  1606   }
  1663   }
  1607 
  1664 
  1608   return 0;
  1665   return 0;
  1609 }
  1666 }
  1610 
  1667 
  1625   unsigned int i;
  1682   unsigned int i;
  1626   int ret = 0;
  1683   int ret = 0;
  1627 
  1684 
  1628   for (i = 0; i < master->slave_count; i++)
  1685   for (i = 0; i < master->slave_count; i++)
  1629   {
  1686   {
  1630     EC_DBG("Deactivate Slave: %d\n",i);
       
  1631     
       
  1632     if (EtherCAT_deactivate_slave(master, &master->slaves[i]) < 0)
  1687     if (EtherCAT_deactivate_slave(master, &master->slaves[i]) < 0)
  1633     {
  1688     {
  1634       ret = -1;
  1689       ret = -1;
  1635     }
  1690     }
  1636     
       
  1637     EC_DBG("done...\n");
       
  1638   }
  1691   }
  1639 
  1692 
  1640   return ret;
  1693   return ret;
  1641 }
  1694 }
  1642 
  1695 
  1661     EtherCAT_command_clear(master->process_data_command);
  1714     EtherCAT_command_clear(master->process_data_command);
  1662     master->process_data_command = NULL;
  1715     master->process_data_command = NULL;
  1663   }
  1716   }
  1664 
  1717 
  1665   if ((master->process_data_command
  1718   if ((master->process_data_command
  1666        = EtherCAT_logical_read_write(master, 0,
  1719        = EtherCAT_logical_read_write(master,
  1667                                      master->process_data_length,
  1720                                      0, master->process_data_length,
  1668                                      master->process_data)) == NULL)
  1721                                      master->process_data)) == NULL)
  1669   {
  1722   {
  1670     EC_DBG(KERN_ERR "EtherCAT: Could not allocate process data command!\n");
  1723     EC_DBG(KERN_ERR "EtherCAT: Could not allocate process data command!\n");
  1671     return -1;
  1724     return -1;
  1672   }
  1725   }
  1730 }
  1783 }
  1731 
  1784 
  1732 /***************************************************************/
  1785 /***************************************************************/
  1733 
  1786 
  1734 /**
  1787 /**
       
  1788    Verwirft ein zuvor gesendetes Prozessdatenkommando.
       
  1789 
       
  1790    Diese Funktion sollte nach Ende des zyklischen Betriebes
       
  1791    aufgerufen werden, um das noch wartende Prozessdaten-Kommando
       
  1792    zu entfernen.
       
  1793 
       
  1794    @param master EtherCAT-Master
       
  1795 */
       
  1796 
       
  1797 void EtherCAT_clear_process_data(EtherCAT_master_t *master)
       
  1798 {
       
  1799   if (!master->process_data_command) return;
       
  1800 
       
  1801   EtherCAT_remove_command(master, master->process_data_command);
       
  1802   EtherCAT_command_clear(master->process_data_command);
       
  1803   master->process_data_command = NULL;
       
  1804 }
       
  1805 
       
  1806 /***************************************************************/
       
  1807 
       
  1808 /**
  1735    Setzt einen Byte-Wert im Speicher.
  1809    Setzt einen Byte-Wert im Speicher.
  1736 
  1810 
  1737    @param data Startadresse
  1811    @param data Startadresse
  1738    @param offset Byte-Offset
  1812    @param offset Byte-Offset
  1739    @param value Wert
  1813    @param value Wert