modbus-data.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. /*
  2. * Copyright © 2010 Stéphane Raimbault <stephane.raimbault@gmail.com>
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Lesser Public License as published by
  6. * the Free Software Foundation; either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program 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
  12. * GNU Lesser Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser Public License
  15. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. */
  17. #include <stdlib.h>
  18. #include <stdint.h>
  19. #include <string.h>
  20. #include <assert.h>
  21. /* Sets many bits from a single byte value (all 8 bits of the byte value are
  22. set) */
  23. void modbus_set_bits_from_byte(uint8_t *dest, int address, const uint8_t value)
  24. {
  25. int i;
  26. for (i=0; i<8; i++) {
  27. dest[address+i] = (value & (1 << i)) ? 1 : 0;
  28. }
  29. }
  30. /* Sets many bits from a table of bytes (only the bits between address and
  31. address + nb_bits are set) */
  32. void modbus_set_bits_from_bytes(uint8_t *dest, int address, unsigned int nb_bits,
  33. const uint8_t *tab_byte)
  34. {
  35. int i;
  36. int shift = 0;
  37. for (i = address; i < address + nb_bits; i++) {
  38. dest[i] = tab_byte[(i - address) / 8] & (1 << shift) ? 1 : 0;
  39. /* gcc doesn't like: shift = (++shift) % 8; */
  40. shift++;
  41. shift %= 8;
  42. }
  43. }
  44. /* Gets the byte value from many bits.
  45. To obtain a full byte, set nb_bits to 8. */
  46. uint8_t modbus_get_byte_from_bits(const uint8_t *src, int address,
  47. unsigned int nb_bits)
  48. {
  49. int i;
  50. uint8_t value = 0;
  51. if (nb_bits > 8) {
  52. /* Assert is ignored if NDEBUG is set */
  53. assert(nb_bits < 8);
  54. nb_bits = 8;
  55. }
  56. for (i=0; i < nb_bits; i++) {
  57. value |= (src[address+i] << i);
  58. }
  59. return value;
  60. }
  61. /* Get a float from 4 bytes in Modbus format */
  62. float modbus_get_float(const uint16_t *src)
  63. {
  64. float r = 0.0f;
  65. uint32_t i;
  66. i = (((uint32_t)src[1]) << 16) + src[0];
  67. memcpy(&r, &i, sizeof (r));
  68. return r;
  69. }
  70. /* Set a float to 4 bytes in Modbus format */
  71. void modbus_set_float(float real, uint16_t *dest)
  72. {
  73. uint32_t i = 0;
  74. memcpy(&i, &real, sizeof (i));
  75. dest[0] = (uint16_t)i;
  76. dest[1] = (uint16_t)(i >> 16);
  77. }