Line data Source code
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 : 7 : This program is distributed in the hope that it will be useful, 8 : but WITHOUT ANY WARRANTY; without even the implied warranty of 9 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 : GNU General Public License for more details. 11 : 12 : You should have received a copy of the GNU General Public License 13 : along with this program. If not, see <http://www.gnu.org/licenses/>. 14 : */ 15 : /* 16 : Scripting CANSensor class, for easy scripting CAN support 17 : */ 18 : #include "AP_Scripting_CANSensor.h" 19 : #include <AP_Math/AP_Math.h> 20 : 21 : #if AP_SCRIPTING_CAN_SENSOR_ENABLED 22 : 23 : // handler for outgoing frames, using uint32 24 0 : bool ScriptingCANSensor::write_frame(AP_HAL::CANFrame &out_frame, const uint32_t timeout_us) 25 : { 26 0 : return CANSensor::write_frame(out_frame, timeout_us); 27 : }; 28 : 29 : // handler for incoming frames, add to buffers 30 0 : void ScriptingCANSensor::handle_frame(AP_HAL::CANFrame &frame) 31 : { 32 0 : WITH_SEMAPHORE(sem); 33 0 : if (buffer_list != nullptr) { 34 0 : buffer_list->handle_frame(frame); 35 : } 36 0 : } 37 : 38 : // add a new buffer to this sensor 39 0 : ScriptingCANBuffer* ScriptingCANSensor::add_buffer(uint32_t buffer_len) 40 : { 41 0 : WITH_SEMAPHORE(sem); 42 0 : ScriptingCANBuffer *new_buff = NEW_NOTHROW ScriptingCANBuffer(*this, buffer_len); 43 0 : if (buffer_list == nullptr) { 44 0 : buffer_list = new_buff; 45 : } else { 46 0 : buffer_list->add_buffer(new_buff); 47 : } 48 0 : return new_buff; 49 0 : } 50 : 51 : // Call main sensor write method 52 0 : bool ScriptingCANBuffer::write_frame(AP_HAL::CANFrame &out_frame, const uint32_t timeout_us) 53 : { 54 0 : return sensor.write_frame(out_frame, timeout_us); 55 : }; 56 : 57 : // read a frame from the buffer 58 0 : bool ScriptingCANBuffer::read_frame(AP_HAL::CANFrame &frame) 59 : { 60 0 : return buffer.pop(frame); 61 : } 62 : 63 : // recursively add frame to buffer 64 0 : void ScriptingCANBuffer::handle_frame(AP_HAL::CANFrame &frame) 65 : { 66 : // accept everything if no filters are setup 67 0 : bool accept = num_filters == 0; 68 : 69 : // Check if frame matches any filters 70 0 : for (uint8_t i = 0; i < MIN(num_filters, ARRAY_SIZE(filter)); i++) { 71 0 : if ((frame.id & filter[i].mask) == filter[i].value) { 72 0 : accept = true; 73 0 : break; 74 : } 75 : } 76 : 77 0 : WITH_SEMAPHORE(sem); 78 : 79 : // Add to buffer for scripting to read 80 0 : if (accept) { 81 0 : buffer.push(frame); 82 : } 83 : 84 : // filtering is not applied to other buffers 85 0 : if (next != nullptr) { 86 0 : next->handle_frame(frame); 87 : } 88 0 : } 89 : 90 : // recursively add new buffer 91 0 : void ScriptingCANBuffer::add_buffer(ScriptingCANBuffer* new_buff) { 92 0 : WITH_SEMAPHORE(sem); 93 0 : if (next == nullptr) { 94 0 : next = new_buff; 95 0 : return; 96 : } 97 0 : next->add_buffer(new_buff); 98 0 : } 99 : 100 : // Add a filter, will pass ID's that match value given the mask 101 0 : bool ScriptingCANBuffer::add_filter(uint32_t mask, uint32_t value) { 102 : 103 : // Run out of filters 104 0 : if (num_filters >= ARRAY_SIZE(filter)) { 105 0 : return false; 106 : } 107 : 108 : // Add to list and increment 109 0 : filter[num_filters].mask = mask; 110 0 : filter[num_filters].value = value & mask; 111 0 : num_filters++; 112 0 : return true; 113 : } 114 : 115 : #endif // AP_SCRIPTING_CAN_SENSOR_ENABLED