master/device.c
changeset 98 f564d0929292
parent 97 e6264685dd7b
child 101 b0c19892145a
equal deleted inserted replaced
97:e6264685dd7b 98:f564d0929292
    17 #include "device.h"
    17 #include "device.h"
    18 #include "master.h"
    18 #include "master.h"
    19 
    19 
    20 /*****************************************************************************/
    20 /*****************************************************************************/
    21 
    21 
       
    22 void ec_data_print(const uint8_t *, size_t);
       
    23 void ec_data_print_diff(const uint8_t *, const uint8_t *, size_t);
       
    24 
       
    25 /*****************************************************************************/
       
    26 
    22 /**
    27 /**
    23    EtherCAT-Geräte-Konstuktor.
    28    EtherCAT-Geräte-Konstuktor.
    24 
    29 
    25    \return 0 wenn alles ok, < 0 bei Fehler (zu wenig Speicher)
    30    \return 0 wenn alles ok, < 0 bei Fehler (zu wenig Speicher)
    26 */
    31 */
    27 
    32 
    28 int ec_device_init(ec_device_t *device, /**< EtherCAT-Gerät */
    33 int ec_device_init(ec_device_t *device, /**< EtherCAT-Gerät */
    29                    ec_master_t *master /**< Zugehöriger Master */
    34                    ec_master_t *master, /**< Zugehöriger Master */
       
    35                    struct net_device *net_dev, /**< Net-Device */
       
    36                    ec_isr_t isr, /**< Adresse der ISR */
       
    37                    struct module *module /**< Modul-Adresse */
    30                    )
    38                    )
    31 {
    39 {
       
    40     struct ethhdr *eth;
       
    41 
    32     device->master = master;
    42     device->master = master;
    33     device->dev = NULL;
    43     device->dev = net_dev;
       
    44     device->isr = isr;
       
    45     device->module = module;
       
    46 
    34     device->open = 0;
    47     device->open = 0;
    35     device->tx_time = 0;
       
    36     device->rx_time = 0;
       
    37     device->state = EC_DEVICE_STATE_READY;
       
    38     device->rx_data_size = 0;
       
    39     device->isr = NULL;
       
    40     device->module = NULL;
       
    41     device->error_reported = 0;
       
    42     device->link_state = 0; // down
    48     device->link_state = 0; // down
    43 
    49 
    44     if ((device->tx_skb = dev_alloc_skb(ETH_HLEN + EC_MAX_FRAME_SIZE)) == NULL) {
    50     if (!(device->tx_skb = dev_alloc_skb(ETH_HLEN + EC_MAX_FRAME_SIZE))) {
    45         EC_ERR("Error allocating device socket buffer!\n");
    51         EC_ERR("Error allocating device socket buffer!\n");
    46         return -1;
    52         return -1;
    47     }
    53     }
    48 
    54 
       
    55     device->tx_skb->dev = net_dev;
       
    56 
       
    57     // Ethernet-II-Header hinzufuegen
       
    58     skb_reserve(device->tx_skb, ETH_HLEN);
       
    59     eth = (struct ethhdr *) skb_push(device->tx_skb, ETH_HLEN);
       
    60     eth->h_proto = htons(0x88A4);
       
    61     memcpy(eth->h_source, net_dev->dev_addr, net_dev->addr_len);
       
    62     memset(eth->h_dest, 0xFF, net_dev->addr_len);
       
    63 
    49     return 0;
    64     return 0;
    50 }
    65 }
    51 
    66 
    52 /*****************************************************************************/
    67 /*****************************************************************************/
    53 
    68 
    59 */
    74 */
    60 
    75 
    61 void ec_device_clear(ec_device_t *device /**< EtherCAT-Gerät */)
    76 void ec_device_clear(ec_device_t *device /**< EtherCAT-Gerät */)
    62 {
    77 {
    63     if (device->open) ec_device_close(device);
    78     if (device->open) ec_device_close(device);
    64 
    79     if (device->tx_skb) dev_kfree_skb(device->tx_skb);
    65     device->dev = NULL;
       
    66 
       
    67     if (device->tx_skb) {
       
    68         dev_kfree_skb(device->tx_skb);
       
    69         device->tx_skb = NULL;
       
    70     }
       
    71 }
    80 }
    72 
    81 
    73 /*****************************************************************************/
    82 /*****************************************************************************/
    74 
    83 
    75 /**
    84 /**
    98     }
   107     }
    99 
   108 
   100     // Device could have received frames before
   109     // Device could have received frames before
   101     for (i = 0; i < 4; i++) ec_device_call_isr(device);
   110     for (i = 0; i < 4; i++) ec_device_call_isr(device);
   102 
   111 
   103     // Reset old device state
       
   104     device->state = EC_DEVICE_STATE_READY;
       
   105     device->link_state = 0;
   112     device->link_state = 0;
   106 
   113 
   107     if (device->dev->open(device->dev) == 0) device->open = 1;
   114     if (device->dev->open(device->dev) == 0) device->open = 1;
   108 
   115 
   109     return device->open ? 0 : -1;
   116     return device->open ? 0 : -1;
   125         return -1;
   132         return -1;
   126     }
   133     }
   127 
   134 
   128     if (!device->open) {
   135     if (!device->open) {
   129         EC_WARN("Device already closed!\n");
   136         EC_WARN("Device already closed!\n");
   130     }
   137         return 0;
   131     else {
   138     }
   132         if (device->dev->stop(device->dev) == 0) device->open = 0;
   139 
   133     }
   140     if (device->dev->stop(device->dev) == 0) device->open = 0;
   134 
   141 
   135     return !device->open ? 0 : -1;
   142     return !device->open ? 0 : -1;
   136 }
   143 }
   137 
   144 
   138 /*****************************************************************************/
   145 /*****************************************************************************/
   139 
   146 
   140 /**
   147 /**
   141    Bereitet den geräteinternen Socket-Buffer auf den Versand vor.
   148    Liefert einen Zeiger auf den Sende-Speicher.
   142 
   149 
   143    \return Zeiger auf den Speicher, in den die Frame-Daten sollen.
   150    \return Zeiger auf den Speicher, in den die Frame-Daten sollen.
   144 */
   151 */
   145 
   152 
   146 uint8_t *ec_device_prepare(ec_device_t *device /**< EtherCAT-Gerät */)
   153 uint8_t *ec_device_tx_data(ec_device_t *device /**< EtherCAT-Gerät */)
   147 {
   154 {
   148     skb_trim(device->tx_skb, 0); // Auf Länge 0 abschneiden
   155     return device->tx_skb->data + ETH_HLEN;
   149     skb_reserve(device->tx_skb, ETH_HLEN); // Reserve für Ethernet-II-Header
       
   150 
       
   151     // Vorerst Speicher für maximal langen Frame reservieren
       
   152     return skb_put(device->tx_skb, EC_MAX_FRAME_SIZE);
       
   153 }
   156 }
   154 
   157 
   155 /*****************************************************************************/
   158 /*****************************************************************************/
   156 
   159 
   157 /**
   160 /**
   161    fügt den Ethernet-II-Header an und ruft die start_xmit()-Funktion der
   164    fügt den Ethernet-II-Header an und ruft die start_xmit()-Funktion der
   162    Netzwerkkarte auf.
   165    Netzwerkkarte auf.
   163 */
   166 */
   164 
   167 
   165 void ec_device_send(ec_device_t *device, /**< EtherCAT-Gerät */
   168 void ec_device_send(ec_device_t *device, /**< EtherCAT-Gerät */
   166                     unsigned int length /**< Länge der zu sendenden Daten */
   169                     size_t size /**< Größe der zu sendenden Daten */
   167                     )
   170                     )
   168 {
   171 {
   169     struct ethhdr *eth;
       
   170 
       
   171     if (unlikely(!device->link_state)) // Link down
   172     if (unlikely(!device->link_state)) // Link down
   172         return;
   173         return;
   173 
   174 
   174     // Framegröße auf (jetzt bekannte) Länge abschneiden
   175     // Framegröße auf (jetzt bekannte) Länge abschneiden
   175     skb_trim(device->tx_skb, length);
   176     device->tx_skb->len = ETH_HLEN + size;
   176 
       
   177     // Ethernet-II-Header hinzufuegen
       
   178     eth = (struct ethhdr *) skb_push(device->tx_skb, ETH_HLEN);
       
   179     eth->h_proto = htons(0x88A4);
       
   180     memcpy(eth->h_source, device->dev->dev_addr, device->dev->addr_len);
       
   181     memset(eth->h_dest, 0xFF, device->dev->addr_len);
       
   182 
       
   183     device->state = EC_DEVICE_STATE_SENT;
       
   184     device->rx_data_size = 0;
       
   185 
   177 
   186     if (unlikely(device->master->debug_level > 1)) {
   178     if (unlikely(device->master->debug_level > 1)) {
   187         EC_DBG("Sending frame:\n");
   179         EC_DBG("sending frame:\n");
   188         ec_data_print(device->tx_skb->data + ETH_HLEN, device->tx_skb->len);
   180         ec_data_print(device->tx_skb->data + ETH_HLEN, size);
   189     }
   181     }
   190 
   182 
   191     // Senden einleiten
   183     // Senden einleiten
   192     rdtscl(device->tx_time); // Get CPU cycles
       
   193     device->dev->hard_start_xmit(device->tx_skb, device->dev);
   184     device->dev->hard_start_xmit(device->tx_skb, device->dev);
   194 }
   185 }
   195 
   186 
   196 /*****************************************************************************/
   187 /*****************************************************************************/
   197 
   188 
   198 /**
   189 /**
   199    Gibt die Anzahl der empfangenen Bytes zurück.
       
   200 
       
   201    \return Empfangene Bytes, oder 0, wenn kein Frame empfangen wurde.
       
   202 */
       
   203 
       
   204 unsigned int ec_device_received(const ec_device_t *device)
       
   205 {
       
   206     return device->rx_data_size;
       
   207 }
       
   208 
       
   209 /*****************************************************************************/
       
   210 
       
   211 /**
       
   212    Gibt die empfangenen Daten zurück.
       
   213 
       
   214    \return Zeiger auf empfangene Daten.
       
   215 */
       
   216 
       
   217 uint8_t *ec_device_data(ec_device_t *device)
       
   218 {
       
   219     return device->rx_data;
       
   220 }
       
   221 
       
   222 /*****************************************************************************/
       
   223 
       
   224 /**
       
   225    Ruft die Interrupt-Routine der Netzwerkkarte auf.
   190    Ruft die Interrupt-Routine der Netzwerkkarte auf.
   226 */
   191 */
   227 
   192 
   228 void ec_device_call_isr(ec_device_t *device /**< EtherCAT-Gerät */)
   193 void ec_device_call_isr(ec_device_t *device /**< EtherCAT-Gerät */)
   229 {
   194 {
   230     if (likely(device->isr)) device->isr(0, device->dev, NULL);
   195     if (likely(device->isr)) device->isr(0, device->dev, NULL);
   231 }
       
   232 
       
   233 /*****************************************************************************/
       
   234 
       
   235 /**
       
   236    Gibt alle Informationen über das Device-Objekt aus.
       
   237 */
       
   238 
       
   239 void ec_device_print(ec_device_t *device /**< EtherCAT-Gerät */)
       
   240 {
       
   241     EC_DBG("---EtherCAT device information begin---\n");
       
   242 
       
   243     if (device) {
       
   244         EC_DBG("Assigned net_device: %X\n", (u32) device->dev);
       
   245         EC_DBG("Transmit socket buffer: %X\n", (u32) device->tx_skb);
       
   246         EC_DBG("Time of last transmission: %u\n", (u32) device->tx_time);
       
   247         EC_DBG("Time of last receive: %u\n", (u32) device->rx_time);
       
   248         EC_DBG("Actual device state: %i\n", (u8) device->state);
       
   249         EC_DBG("Receive buffer: %X\n", (u32) device->rx_data);
       
   250         EC_DBG("Receive buffer fill state: %u/%u\n",
       
   251                (u32) device->rx_data_size, EC_MAX_FRAME_SIZE);
       
   252     }
       
   253     else {
       
   254         EC_DBG("Device is NULL!\n");
       
   255     }
       
   256 
       
   257     EC_DBG("---EtherCAT device information end---\n");
       
   258 }
       
   259 
       
   260 /*****************************************************************************/
       
   261 
       
   262 /**
       
   263    Gibt das letzte Rahmenpaar aus.
       
   264 */
       
   265 
       
   266 void ec_device_debug(const ec_device_t *device /**< EtherCAT-Gerät */)
       
   267 {
       
   268     EC_DBG(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
       
   269     ec_data_print(device->tx_skb->data + ETH_HLEN, device->tx_skb->len);
       
   270     EC_DBG("--------------------------------------\n");
       
   271     ec_data_print_diff(device->tx_skb->data + ETH_HLEN, device->rx_data,
       
   272                        device->rx_data_size);
       
   273     EC_DBG("<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n");
       
   274 }
   196 }
   275 
   197 
   276 /*****************************************************************************/
   198 /*****************************************************************************/
   277 
   199 
   278 /**
   200 /**
   326  * Treiberschnittstelle
   248  * Treiberschnittstelle
   327  *
   249  *
   328  *****************************************************************************/
   250  *****************************************************************************/
   329 
   251 
   330 /**
   252 /**
   331    Setzt den Zustand des EtherCAT-Gerätes.
       
   332 */
       
   333 
       
   334 void EtherCAT_dev_state(ec_device_t *device,  /**< EtherCAT-Gerät */
       
   335                         ec_device_state_t state /**< Neuer Zustand */
       
   336                         )
       
   337 {
       
   338     device->state = state;
       
   339 }
       
   340 
       
   341 /*****************************************************************************/
       
   342 
       
   343 /**
       
   344    Prüft, ob das Net-Device \a dev zum registrierten EtherCAT-Gerät gehört.
   253    Prüft, ob das Net-Device \a dev zum registrierten EtherCAT-Gerät gehört.
   345 
   254 
   346    \return 0 wenn nein, nicht-null wenn ja.
   255    \return 0 wenn nein, nicht-null wenn ja.
   347 */
   256 */
   348 
   257 
   364 void EtherCAT_dev_receive(ec_device_t *device, /**< EtherCAT-Gerät */
   273 void EtherCAT_dev_receive(ec_device_t *device, /**< EtherCAT-Gerät */
   365                           const void *data, /**< Zeiger auf empfangene Daten */
   274                           const void *data, /**< Zeiger auf empfangene Daten */
   366                           size_t size /**< Größe der empfangenen Daten */
   275                           size_t size /**< Größe der empfangenen Daten */
   367                           )
   276                           )
   368 {
   277 {
   369     // Copy received data to ethercat-device buffer
       
   370     memcpy(device->rx_data, data, size);
       
   371     device->rx_data_size = size;
       
   372     device->state = EC_DEVICE_STATE_RECEIVED;
       
   373 
       
   374     if (unlikely(device->master->debug_level > 1)) {
   278     if (unlikely(device->master->debug_level > 1)) {
   375         EC_DBG("Received frame:\n");
   279         EC_DBG("Received frame:\n");
   376         ec_data_print_diff(device->tx_skb->data + ETH_HLEN, device->rx_data,
   280         ec_data_print_diff(device->tx_skb->data + ETH_HLEN, data, size);
   377                            device->rx_data_size);
   281     }
   378     }
   282 
       
   283     ec_master_receive(device->master, data, size);
   379 }
   284 }
   380 
   285 
   381 /*****************************************************************************/
   286 /*****************************************************************************/
   382 
   287 
   383 /**
   288 /**
   395 }
   300 }
   396 
   301 
   397 /*****************************************************************************/
   302 /*****************************************************************************/
   398 
   303 
   399 EXPORT_SYMBOL(EtherCAT_dev_is_ec);
   304 EXPORT_SYMBOL(EtherCAT_dev_is_ec);
   400 EXPORT_SYMBOL(EtherCAT_dev_state);
       
   401 EXPORT_SYMBOL(EtherCAT_dev_receive);
   305 EXPORT_SYMBOL(EtherCAT_dev_receive);
   402 EXPORT_SYMBOL(EtherCAT_dev_link_state);
   306 EXPORT_SYMBOL(EtherCAT_dev_link_state);
   403 
   307 
   404 /*****************************************************************************/
   308 /*****************************************************************************/
   405 
   309