GCS_DeviceOp.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /*
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. */
  13. /*
  14. handle device operations over MAVLink
  15. */
  16. #include <AP_HAL/AP_HAL.h>
  17. #include <AP_HAL/Device.h>
  18. #include <AP_HAL/I2CDevice.h>
  19. #include "GCS.h"
  20. #include <stdio.h>
  21. extern const AP_HAL::HAL& hal;
  22. /*
  23. handle DEVICE_OP_READ message
  24. */
  25. void GCS_MAVLINK::handle_device_op_read(const mavlink_message_t &msg)
  26. {
  27. mavlink_device_op_read_t packet;
  28. mavlink_msg_device_op_read_decode(&msg, &packet);
  29. AP_HAL::OwnPtr<AP_HAL::Device> dev = nullptr;
  30. uint8_t retcode = 0;
  31. uint8_t data[sizeof(mavlink_device_op_read_reply_t::data)] {};
  32. bool ret = false;
  33. uint8_t regstart = packet.regstart;
  34. if (packet.bustype == DEVICE_OP_BUSTYPE_I2C) {
  35. dev = hal.i2c_mgr->get_device(packet.bus, packet.address);
  36. } else if (packet.bustype == DEVICE_OP_BUSTYPE_SPI) {
  37. dev = hal.spi->get_device(packet.busname);
  38. } else {
  39. retcode = 1;
  40. goto fail;
  41. }
  42. if (!dev) {
  43. retcode = 2;
  44. goto fail;
  45. }
  46. if (!dev->get_semaphore()->take(10)) {
  47. retcode = 3;
  48. goto fail;
  49. }
  50. if (regstart == 0xff) {
  51. // assume raw transfer, non-register interface
  52. ret = dev->transfer(nullptr, 0, data, packet.count);
  53. // reply using register start 0 for display purposes
  54. regstart = 0;
  55. } else {
  56. ret = dev->read_registers(packet.regstart, data, packet.count);
  57. }
  58. dev->get_semaphore()->give();
  59. if (!ret) {
  60. retcode = 4;
  61. goto fail;
  62. }
  63. mavlink_msg_device_op_read_reply_send(
  64. chan,
  65. packet.request_id,
  66. retcode,
  67. regstart,
  68. packet.count,
  69. data);
  70. return;
  71. fail:
  72. mavlink_msg_device_op_read_reply_send(
  73. chan,
  74. packet.request_id,
  75. retcode,
  76. packet.regstart,
  77. 0,
  78. nullptr);
  79. }
  80. /*
  81. handle DEVICE_OP_WRITE message
  82. */
  83. void GCS_MAVLINK::handle_device_op_write(const mavlink_message_t &msg)
  84. {
  85. mavlink_device_op_write_t packet;
  86. mavlink_msg_device_op_write_decode(&msg, &packet);
  87. AP_HAL::OwnPtr<AP_HAL::Device> dev = nullptr;
  88. uint8_t retcode = 0;
  89. if (packet.bustype == DEVICE_OP_BUSTYPE_I2C) {
  90. dev = hal.i2c_mgr->get_device(packet.bus, packet.address);
  91. } else if (packet.bustype == DEVICE_OP_BUSTYPE_SPI) {
  92. dev = hal.spi->get_device(packet.busname);
  93. } else {
  94. retcode = 1;
  95. goto fail;
  96. }
  97. if (!dev) {
  98. retcode = 2;
  99. goto fail;
  100. }
  101. if (!dev->get_semaphore()->take(10)) {
  102. retcode = 3;
  103. goto fail;
  104. }
  105. if (packet.regstart == 0xff) {
  106. // assume raw transfer, non-register interface
  107. if (!dev->transfer(packet.data, packet.count, nullptr, 0)) {
  108. retcode = 4;
  109. }
  110. } else {
  111. for (uint8_t i=0; i<packet.count; i++) {
  112. if (!dev->write_register(packet.regstart+i, packet.data[i])) {
  113. retcode = 4;
  114. break;
  115. }
  116. }
  117. }
  118. dev->get_semaphore()->give();
  119. fail:
  120. mavlink_msg_device_op_write_reply_send(
  121. chan,
  122. packet.request_id,
  123. retcode);
  124. }