/* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /* handle device operations over MAVLink */ #include "GCS_config.h" #if AP_MAVLINK_MSG_DEVICE_OP_ENABLED #include #include #include #include "GCS.h" #include extern const AP_HAL::HAL& hal; /* handle DEVICE_OP_READ message */ void GCS_MAVLINK::handle_device_op_read(const mavlink_message_t &msg) { mavlink_device_op_read_t packet; mavlink_msg_device_op_read_decode(&msg, &packet); AP_HAL::OwnPtr dev = nullptr; uint8_t retcode = 0; uint8_t data[sizeof(mavlink_device_op_read_reply_t::data)] {}; bool ret = false; uint8_t regstart = packet.regstart; if (packet.bustype == DEVICE_OP_BUSTYPE_I2C) { dev = hal.i2c_mgr->get_device(packet.bus, packet.address); } else if (packet.bustype == DEVICE_OP_BUSTYPE_SPI) { dev = hal.spi->get_device(packet.busname); } else { retcode = 1; goto fail; } if (!dev) { retcode = 2; goto fail; } if (packet.count > sizeof(data)) { retcode = 5; goto fail; } if (!dev->get_semaphore()->take(10)) { retcode = 3; goto fail; } if (regstart == 0xff) { // assume raw transfer, non-register interface ret = dev->transfer_bank(packet.bank, nullptr, 0, data, packet.count); // reply using register start 0 for display purposes regstart = 0; } else { ret = dev->read_bank_registers(packet.bank, packet.regstart, data, packet.count); } dev->get_semaphore()->give(); if (!ret) { retcode = 4; goto fail; } mavlink_msg_device_op_read_reply_send( chan, packet.request_id, retcode, regstart, packet.count, data, packet.bank); return; fail: mavlink_msg_device_op_read_reply_send( chan, packet.request_id, retcode, packet.regstart, 0, nullptr, packet.bank); } /* handle DEVICE_OP_WRITE message */ void GCS_MAVLINK::handle_device_op_write(const mavlink_message_t &msg) { mavlink_device_op_write_t packet; mavlink_msg_device_op_write_decode(&msg, &packet); AP_HAL::OwnPtr dev = nullptr; uint8_t retcode = 0; if (packet.bustype == DEVICE_OP_BUSTYPE_I2C) { dev = hal.i2c_mgr->get_device(packet.bus, packet.address); } else if (packet.bustype == DEVICE_OP_BUSTYPE_SPI) { dev = hal.spi->get_device(packet.busname); } else { retcode = 1; goto fail; } if (!dev) { retcode = 2; goto fail; } if (!dev->get_semaphore()->take(10)) { retcode = 3; goto fail; } if (packet.regstart == 0xff) { // assume raw transfer, non-register interface if (!dev->transfer_bank(packet.bank, packet.data, packet.count, nullptr, 0)) { retcode = 4; } } else { for (uint8_t i=0; iwrite_bank_register(packet.bank, packet.regstart+i, packet.data[i])) { retcode = 4; break; } } } dev->get_semaphore()->give(); fail: mavlink_msg_device_op_write_reply_send( chan, packet.request_id, retcode); } #endif // AP_MAVLINK_MSG_DEVICE_OP_ENABLED