modbus-data.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*
  2. * Copyright © 2010-2011 Stéphane Raimbault <stephane.raimbault@gmail.com>
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with this library; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include <stdlib.h>
  19. #ifndef _MSC_VER
  20. #include <stdint.h>
  21. #else
  22. #include "stdint.h"
  23. #endif
  24. #include <string.h>
  25. #include <assert.h>
  26. #include <byteswap.h>
  27. #include "modbus.h"
  28. /* Sets many bits from a single byte value (all 8 bits of the byte value are
  29. set) */
  30. void modbus_set_bits_from_byte(uint8_t *dest, int index, const uint8_t value)
  31. {
  32. int i;
  33. for (i=0; i < 8; i++) {
  34. dest[index+i] = (value & (1 << i)) ? 1 : 0;
  35. }
  36. }
  37. /* Sets many bits from a table of bytes (only the bits between index and
  38. index + nb_bits are set) */
  39. void modbus_set_bits_from_bytes(uint8_t *dest, int index, unsigned int nb_bits,
  40. const uint8_t *tab_byte)
  41. {
  42. unsigned int i;
  43. int shift = 0;
  44. for (i = index; i < index + nb_bits; i++) {
  45. dest[i] = tab_byte[(i - index) / 8] & (1 << shift) ? 1 : 0;
  46. /* gcc doesn't like: shift = (++shift) % 8; */
  47. shift++;
  48. shift %= 8;
  49. }
  50. }
  51. /* Gets the byte value from many bits.
  52. To obtain a full byte, set nb_bits to 8. */
  53. uint8_t modbus_get_byte_from_bits(const uint8_t *src, int index,
  54. unsigned int nb_bits)
  55. {
  56. unsigned int i;
  57. uint8_t value = 0;
  58. if (nb_bits > 8) {
  59. /* Assert is ignored if NDEBUG is set */
  60. assert(nb_bits < 8);
  61. nb_bits = 8;
  62. }
  63. for (i=0; i < nb_bits; i++) {
  64. value |= (src[index+i] << i);
  65. }
  66. return value;
  67. }
  68. /* Get a float from 4 bytes in Modbus format (ABCD) */
  69. float modbus_get_float(const uint16_t *src)
  70. {
  71. float f;
  72. uint32_t i;
  73. i = (((uint32_t)src[1]) << 16) + src[0];
  74. memcpy(&f, &i, sizeof(float));
  75. return f;
  76. }
  77. /* Get a float from 4 bytes in swapped Modbus format (DCBA) */
  78. float modbus_get_float_swapped(const uint16_t *src)
  79. {
  80. float f;
  81. uint32_t i;
  82. i = bswap_32((((uint32_t)src[1]) << 16) + src[0]);
  83. memcpy(&f, &i, sizeof(float));
  84. return f;
  85. }
  86. /* Set a float to 4 bytes in Modbus format (ABCD) */
  87. void modbus_set_float(float f, uint16_t *dest)
  88. {
  89. uint32_t i;
  90. memcpy(&i, &f, sizeof(uint32_t));
  91. dest[0] = (uint16_t)i;
  92. dest[1] = (uint16_t)(i >> 16);
  93. }
  94. /* Set a float to 4 bytes in swapped Modbus format (DCBA) */
  95. void modbus_set_float_swapped(float f, uint16_t *dest)
  96. {
  97. uint32_t i;
  98. memcpy(&i, &f, sizeof(uint32_t));
  99. i = bswap_32(i);
  100. dest[0] = (uint16_t)i;
  101. dest[1] = (uint16_t)(i >> 16);
  102. }