master/datagram.c
changeset 1313 ed15eef57d5c
parent 1312 74853e018898
child 1326 ef907b0b5125
equal deleted inserted replaced
1312:74853e018898 1313:ed15eef57d5c
    46 /*****************************************************************************/
    46 /*****************************************************************************/
    47 
    47 
    48 /** \cond */
    48 /** \cond */
    49 
    49 
    50 #define EC_FUNC_HEADER \
    50 #define EC_FUNC_HEADER \
    51     if (unlikely(ec_datagram_prealloc(datagram, data_size))) \
    51     ret = ec_datagram_prealloc(datagram, data_size); \
    52         return -1; \
    52     if (unlikely(ret)) \
       
    53         return ret; \
    53     datagram->index = 0; \
    54     datagram->index = 0; \
    54     datagram->working_counter = 0; \
    55     datagram->working_counter = 0; \
    55     datagram->state = EC_DATAGRAM_INIT;
    56     datagram->state = EC_DATAGRAM_INIT;
    56 
    57 
    57 #define EC_FUNC_FOOTER \
    58 #define EC_FUNC_FOOTER \
   169 
   170 
   170 /*****************************************************************************/
   171 /*****************************************************************************/
   171 
   172 
   172 /** Initializes an EtherCAT APRD datagram.
   173 /** Initializes an EtherCAT APRD datagram.
   173  *
   174  *
   174  * \return 0 in case of success, else < 0
   175  * \return Return value of ec_datagram_prealloc().
   175  */
   176  */
   176 int ec_datagram_aprd(
   177 int ec_datagram_aprd(
   177         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   178         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   178         uint16_t ring_position, /**< Auto-increment address. */
   179         uint16_t ring_position, /**< Auto-increment address. */
   179         uint16_t mem_address, /**< Physical memory address. */
   180         uint16_t mem_address, /**< Physical memory address. */
   180         size_t data_size /**< Number of bytes to read. */
   181         size_t data_size /**< Number of bytes to read. */
   181         )
   182         )
   182 {
   183 {
       
   184     int ret;
   183     EC_FUNC_HEADER;
   185     EC_FUNC_HEADER;
   184     datagram->type = EC_DATAGRAM_APRD;
   186     datagram->type = EC_DATAGRAM_APRD;
   185     EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
   187     EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
   186     EC_WRITE_U16(datagram->address + 2, mem_address);
   188     EC_WRITE_U16(datagram->address + 2, mem_address);
   187     EC_FUNC_FOOTER;
   189     EC_FUNC_FOOTER;
   189 
   191 
   190 /*****************************************************************************/
   192 /*****************************************************************************/
   191 
   193 
   192 /** Initializes an EtherCAT APWR datagram.
   194 /** Initializes an EtherCAT APWR datagram.
   193  *
   195  *
   194  * \return 0 in case of success, else < 0
   196  * \return Return value of ec_datagram_prealloc().
   195  */
   197  */
   196 int ec_datagram_apwr(
   198 int ec_datagram_apwr(
   197         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   199         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   198         uint16_t ring_position, /**< Auto-increment address. */
   200         uint16_t ring_position, /**< Auto-increment address. */
   199         uint16_t mem_address, /**< Physical memory address. */
   201         uint16_t mem_address, /**< Physical memory address. */
   200         size_t data_size /**< Number of bytes to write. */
   202         size_t data_size /**< Number of bytes to write. */
   201         )
   203         )
   202 {
   204 {
       
   205     int ret;
   203     EC_FUNC_HEADER;
   206     EC_FUNC_HEADER;
   204     datagram->type = EC_DATAGRAM_APWR;
   207     datagram->type = EC_DATAGRAM_APWR;
   205     EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
   208     EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
   206     EC_WRITE_U16(datagram->address + 2, mem_address);
   209     EC_WRITE_U16(datagram->address + 2, mem_address);
   207     EC_FUNC_FOOTER;
   210     EC_FUNC_FOOTER;
   209 
   212 
   210 /*****************************************************************************/
   213 /*****************************************************************************/
   211 
   214 
   212 /** Initializes an EtherCAT APRW datagram.
   215 /** Initializes an EtherCAT APRW datagram.
   213  *
   216  *
   214  * \return 0 in case of success, else < 0
   217  * \return Return value of ec_datagram_prealloc().
   215  */
   218  */
   216 int ec_datagram_aprw(
   219 int ec_datagram_aprw(
   217         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   220         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   218         uint16_t ring_position, /**< Auto-increment address. */
   221         uint16_t ring_position, /**< Auto-increment address. */
   219         uint16_t mem_address, /**< Physical memory address. */
   222         uint16_t mem_address, /**< Physical memory address. */
   220         size_t data_size /**< Number of bytes to write. */
   223         size_t data_size /**< Number of bytes to write. */
   221         )
   224         )
   222 {
   225 {
       
   226     int ret;
   223     EC_FUNC_HEADER;
   227     EC_FUNC_HEADER;
   224     datagram->type = EC_DATAGRAM_APRW;
   228     datagram->type = EC_DATAGRAM_APRW;
   225     EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
   229     EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
   226     EC_WRITE_U16(datagram->address + 2, mem_address);
   230     EC_WRITE_U16(datagram->address + 2, mem_address);
   227     EC_FUNC_FOOTER;
   231     EC_FUNC_FOOTER;
   229 
   233 
   230 /*****************************************************************************/
   234 /*****************************************************************************/
   231 
   235 
   232 /** Initializes an EtherCAT ARMW datagram.
   236 /** Initializes an EtherCAT ARMW datagram.
   233  *
   237  *
   234  * \return 0 in case of success, else < 0
   238  * \return Return value of ec_datagram_prealloc().
   235  */
   239  */
   236 int ec_datagram_armw(
   240 int ec_datagram_armw(
   237         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   241         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   238         uint16_t ring_position, /**< Auto-increment address. */
   242         uint16_t ring_position, /**< Auto-increment address. */
   239         uint16_t mem_address, /**< Physical memory address. */
   243         uint16_t mem_address, /**< Physical memory address. */
   240         size_t data_size /**< Number of bytes to read. */
   244         size_t data_size /**< Number of bytes to read. */
   241         )
   245         )
   242 {
   246 {
       
   247     int ret;
   243     EC_FUNC_HEADER;
   248     EC_FUNC_HEADER;
   244     datagram->type = EC_DATAGRAM_ARMW;
   249     datagram->type = EC_DATAGRAM_ARMW;
   245     EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
   250     EC_WRITE_S16(datagram->address, (int16_t) ring_position * (-1));
   246     EC_WRITE_U16(datagram->address + 2, mem_address);
   251     EC_WRITE_U16(datagram->address + 2, mem_address);
   247     EC_FUNC_FOOTER;
   252     EC_FUNC_FOOTER;
   249 
   254 
   250 /*****************************************************************************/
   255 /*****************************************************************************/
   251 
   256 
   252 /** Initializes an EtherCAT FPRD datagram.
   257 /** Initializes an EtherCAT FPRD datagram.
   253  *
   258  *
   254  * \return 0 in case of success, else < 0
   259  * \return Return value of ec_datagram_prealloc().
   255  */
   260  */
   256 int ec_datagram_fprd(
   261 int ec_datagram_fprd(
   257         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   262         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   258         uint16_t configured_address, /**< Configured station address. */
   263         uint16_t configured_address, /**< Configured station address. */
   259         uint16_t mem_address, /**< Physical memory address. */
   264         uint16_t mem_address, /**< Physical memory address. */
   260         size_t data_size /**< Number of bytes to read. */
   265         size_t data_size /**< Number of bytes to read. */
   261         )
   266         )
   262 {
   267 {
       
   268     int ret;
       
   269 
   263     if (unlikely(configured_address == 0x0000))
   270     if (unlikely(configured_address == 0x0000))
   264         EC_WARN("Using configured station address 0x0000!\n");
   271         EC_WARN("Using configured station address 0x0000!\n");
   265 
   272 
   266     EC_FUNC_HEADER;
   273     EC_FUNC_HEADER;
   267     datagram->type = EC_DATAGRAM_FPRD;
   274     datagram->type = EC_DATAGRAM_FPRD;
   272 
   279 
   273 /*****************************************************************************/
   280 /*****************************************************************************/
   274 
   281 
   275 /** Initializes an EtherCAT FPWR datagram.
   282 /** Initializes an EtherCAT FPWR datagram.
   276  *
   283  *
   277  * \return 0 in case of success, else < 0
   284  * \return Return value of ec_datagram_prealloc().
   278  */
   285  */
   279 int ec_datagram_fpwr(
   286 int ec_datagram_fpwr(
   280         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   287         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   281         uint16_t configured_address, /**< Configured station address. */
   288         uint16_t configured_address, /**< Configured station address. */
   282         uint16_t mem_address, /**< Physical memory address. */
   289         uint16_t mem_address, /**< Physical memory address. */
   283         size_t data_size /**< Number of bytes to write. */
   290         size_t data_size /**< Number of bytes to write. */
   284         )
   291         )
   285 {
   292 {
       
   293     int ret;
       
   294 
   286     if (unlikely(configured_address == 0x0000))
   295     if (unlikely(configured_address == 0x0000))
   287         EC_WARN("Using configured station address 0x0000!\n");
   296         EC_WARN("Using configured station address 0x0000!\n");
   288 
   297 
   289     EC_FUNC_HEADER;
   298     EC_FUNC_HEADER;
   290     datagram->type = EC_DATAGRAM_FPWR;
   299     datagram->type = EC_DATAGRAM_FPWR;
   295 
   304 
   296 /*****************************************************************************/
   305 /*****************************************************************************/
   297 
   306 
   298 /** Initializes an EtherCAT FPRW datagram.
   307 /** Initializes an EtherCAT FPRW datagram.
   299  *
   308  *
   300  * \return 0 in case of success, else < 0
   309  * \return Return value of ec_datagram_prealloc().
   301  */
   310  */
   302 int ec_datagram_fprw(
   311 int ec_datagram_fprw(
   303         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   312         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   304         uint16_t configured_address, /**< Configured station address. */
   313         uint16_t configured_address, /**< Configured station address. */
   305         uint16_t mem_address, /**< Physical memory address. */
   314         uint16_t mem_address, /**< Physical memory address. */
   306         size_t data_size /**< Number of bytes to write. */
   315         size_t data_size /**< Number of bytes to write. */
   307         )
   316         )
   308 {
   317 {
       
   318     int ret;
       
   319 
   309     if (unlikely(configured_address == 0x0000))
   320     if (unlikely(configured_address == 0x0000))
   310         EC_WARN("Using configured station address 0x0000!\n");
   321         EC_WARN("Using configured station address 0x0000!\n");
   311 
   322 
   312     EC_FUNC_HEADER;
   323     EC_FUNC_HEADER;
   313     datagram->type = EC_DATAGRAM_FPRW;
   324     datagram->type = EC_DATAGRAM_FPRW;
   318 
   329 
   319 /*****************************************************************************/
   330 /*****************************************************************************/
   320 
   331 
   321 /** Initializes an EtherCAT FRMW datagram.
   332 /** Initializes an EtherCAT FRMW datagram.
   322  *
   333  *
   323  * \return 0 in case of success, else < 0
   334  * \return Return value of ec_datagram_prealloc().
   324  */
   335  */
   325 int ec_datagram_frmw(
   336 int ec_datagram_frmw(
   326         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   337         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   327         uint16_t configured_address, /**< Configured station address. */
   338         uint16_t configured_address, /**< Configured station address. */
   328         uint16_t mem_address, /**< Physical memory address. */
   339         uint16_t mem_address, /**< Physical memory address. */
   329         size_t data_size /**< Number of bytes to write. */
   340         size_t data_size /**< Number of bytes to write. */
   330         )
   341         )
   331 {
   342 {
       
   343     int ret;
       
   344 
   332     if (unlikely(configured_address == 0x0000))
   345     if (unlikely(configured_address == 0x0000))
   333         EC_WARN("Using configured station address 0x0000!\n");
   346         EC_WARN("Using configured station address 0x0000!\n");
   334 
   347 
   335     EC_FUNC_HEADER;
   348     EC_FUNC_HEADER;
   336     datagram->type = EC_DATAGRAM_FRMW;
   349     datagram->type = EC_DATAGRAM_FRMW;
   341 
   354 
   342 /*****************************************************************************/
   355 /*****************************************************************************/
   343 
   356 
   344 /** Initializes an EtherCAT BRD datagram.
   357 /** Initializes an EtherCAT BRD datagram.
   345  *
   358  *
   346  * \return 0 in case of success, else < 0
   359  * \return Return value of ec_datagram_prealloc().
   347  */
   360  */
   348 int ec_datagram_brd(
   361 int ec_datagram_brd(
   349         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   362         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   350         uint16_t mem_address, /**< Physical memory address. */
   363         uint16_t mem_address, /**< Physical memory address. */
   351         size_t data_size /**< Number of bytes to read. */
   364         size_t data_size /**< Number of bytes to read. */
   352         )
   365         )
   353 {
   366 {
       
   367     int ret;
   354     EC_FUNC_HEADER;
   368     EC_FUNC_HEADER;
   355     datagram->type = EC_DATAGRAM_BRD;
   369     datagram->type = EC_DATAGRAM_BRD;
   356     EC_WRITE_U16(datagram->address, 0x0000);
   370     EC_WRITE_U16(datagram->address, 0x0000);
   357     EC_WRITE_U16(datagram->address + 2, mem_address);
   371     EC_WRITE_U16(datagram->address + 2, mem_address);
   358     EC_FUNC_FOOTER;
   372     EC_FUNC_FOOTER;
   360 
   374 
   361 /*****************************************************************************/
   375 /*****************************************************************************/
   362 
   376 
   363 /** Initializes an EtherCAT BWR datagram.
   377 /** Initializes an EtherCAT BWR datagram.
   364  *
   378  *
   365  * \return 0 in case of success, else < 0
   379  * \return Return value of ec_datagram_prealloc().
   366  */
   380  */
   367 int ec_datagram_bwr(
   381 int ec_datagram_bwr(
   368         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   382         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   369         uint16_t mem_address, /**< Physical memory address. */
   383         uint16_t mem_address, /**< Physical memory address. */
   370         size_t data_size /**< Number of bytes to write. */
   384         size_t data_size /**< Number of bytes to write. */
   371         )
   385         )
   372 {
   386 {
       
   387     int ret;
   373     EC_FUNC_HEADER;
   388     EC_FUNC_HEADER;
   374     datagram->type = EC_DATAGRAM_BWR;
   389     datagram->type = EC_DATAGRAM_BWR;
   375     EC_WRITE_U16(datagram->address, 0x0000);
   390     EC_WRITE_U16(datagram->address, 0x0000);
   376     EC_WRITE_U16(datagram->address + 2, mem_address);
   391     EC_WRITE_U16(datagram->address + 2, mem_address);
   377     EC_FUNC_FOOTER;
   392     EC_FUNC_FOOTER;
   379 
   394 
   380 /*****************************************************************************/
   395 /*****************************************************************************/
   381 
   396 
   382 /** Initializes an EtherCAT BRW datagram.
   397 /** Initializes an EtherCAT BRW datagram.
   383  *
   398  *
   384  * \return 0 in case of success, else < 0
   399  * \return Return value of ec_datagram_prealloc().
   385  */
   400  */
   386 int ec_datagram_brw(
   401 int ec_datagram_brw(
   387         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   402         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   388         uint16_t mem_address, /**< Physical memory address. */
   403         uint16_t mem_address, /**< Physical memory address. */
   389         size_t data_size /**< Number of bytes to write. */
   404         size_t data_size /**< Number of bytes to write. */
   390         )
   405         )
   391 {
   406 {
       
   407     int ret;
   392     EC_FUNC_HEADER;
   408     EC_FUNC_HEADER;
   393     datagram->type = EC_DATAGRAM_BRW;
   409     datagram->type = EC_DATAGRAM_BRW;
   394     EC_WRITE_U16(datagram->address, 0x0000);
   410     EC_WRITE_U16(datagram->address, 0x0000);
   395     EC_WRITE_U16(datagram->address + 2, mem_address);
   411     EC_WRITE_U16(datagram->address + 2, mem_address);
   396     EC_FUNC_FOOTER;
   412     EC_FUNC_FOOTER;
   401 /** Initializes an EtherCAT LRD datagram.
   417 /** Initializes an EtherCAT LRD datagram.
   402  *
   418  *
   403  * \attention It is assumed, that the external memory is at least \a data_size
   419  * \attention It is assumed, that the external memory is at least \a data_size
   404  *            bytes large.
   420  *            bytes large.
   405  *
   421  *
   406  * \return 0 in case of success, else < 0
   422  * \return Return value of ec_datagram_prealloc().
   407  */
   423  */
   408 int ec_datagram_lrd(
   424 int ec_datagram_lrd(
   409         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   425         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   410         uint32_t offset, /**< Logical address. */
   426         uint32_t offset, /**< Logical address. */
   411         size_t data_size, /**< Number of bytes to read/write. */
   427         size_t data_size, /**< Number of bytes to read/write. */
   412         uint8_t *external_memory /**< Pointer to the memory to use. */
   428         uint8_t *external_memory /**< Pointer to the memory to use. */
   413         )
   429         )
   414 {
   430 {
       
   431     int ret;
   415     datagram->data = external_memory;
   432     datagram->data = external_memory;
   416     datagram->data_origin = EC_ORIG_EXTERNAL;
   433     datagram->data_origin = EC_ORIG_EXTERNAL;
   417     EC_FUNC_HEADER;
   434     EC_FUNC_HEADER;
   418     datagram->type = EC_DATAGRAM_LRD;
   435     datagram->type = EC_DATAGRAM_LRD;
   419     EC_WRITE_U32(datagram->address, offset);
   436     EC_WRITE_U32(datagram->address, offset);
   425 /** Initializes an EtherCAT LWR datagram.
   442 /** Initializes an EtherCAT LWR datagram.
   426  *
   443  *
   427  * \attention It is assumed, that the external memory is at least \a data_size
   444  * \attention It is assumed, that the external memory is at least \a data_size
   428  *            bytes large.
   445  *            bytes large.
   429  *
   446  *
   430  * \return 0 in case of success, else < 0
   447  * \return Return value of ec_datagram_prealloc().
   431  */
   448  */
   432 int ec_datagram_lwr(
   449 int ec_datagram_lwr(
   433         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   450         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   434         uint32_t offset, /**< Logical address. */
   451         uint32_t offset, /**< Logical address. */
   435         size_t data_size, /**< Number of bytes to read/write. */
   452         size_t data_size, /**< Number of bytes to read/write. */
   436         uint8_t *external_memory /**< Pointer to the memory to use. */
   453         uint8_t *external_memory /**< Pointer to the memory to use. */
   437         )
   454         )
   438 {
   455 {
       
   456     int ret;
   439     datagram->data = external_memory;
   457     datagram->data = external_memory;
   440     datagram->data_origin = EC_ORIG_EXTERNAL;
   458     datagram->data_origin = EC_ORIG_EXTERNAL;
   441     EC_FUNC_HEADER;
   459     EC_FUNC_HEADER;
   442     datagram->type = EC_DATAGRAM_LWR;
   460     datagram->type = EC_DATAGRAM_LWR;
   443     EC_WRITE_U32(datagram->address, offset);
   461     EC_WRITE_U32(datagram->address, offset);
   449 /** Initializes an EtherCAT LRW datagram.
   467 /** Initializes an EtherCAT LRW datagram.
   450  *
   468  *
   451  * \attention It is assumed, that the external memory is at least \a data_size
   469  * \attention It is assumed, that the external memory is at least \a data_size
   452  *            bytes large.
   470  *            bytes large.
   453  *
   471  *
   454  * \return 0 in case of success, else < 0
   472  * \return Return value of ec_datagram_prealloc().
   455  */
   473  */
   456 int ec_datagram_lrw(
   474 int ec_datagram_lrw(
   457         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   475         ec_datagram_t *datagram, /**< EtherCAT datagram. */
   458         uint32_t offset, /**< Logical address. */
   476         uint32_t offset, /**< Logical address. */
   459         size_t data_size, /**< Number of bytes to read/write. */
   477         size_t data_size, /**< Number of bytes to read/write. */
   460         uint8_t *external_memory /**< Pointer to the memory to use. */
   478         uint8_t *external_memory /**< Pointer to the memory to use. */
   461         )
   479         )
   462 {
   480 {
       
   481     int ret;
   463     datagram->data = external_memory;
   482     datagram->data = external_memory;
   464     datagram->data_origin = EC_ORIG_EXTERNAL;
   483     datagram->data_origin = EC_ORIG_EXTERNAL;
   465     EC_FUNC_HEADER;
   484     EC_FUNC_HEADER;
   466     datagram->type = EC_DATAGRAM_LRW;
   485     datagram->type = EC_DATAGRAM_LRW;
   467     EC_WRITE_U32(datagram->address, offset);
   486     EC_WRITE_U32(datagram->address, offset);