Skip to content

Commit db3ed06

Browse files
committed
WIP: AP_HAL: add CANDriver
1 parent 556993d commit db3ed06

File tree

4 files changed

+102
-0
lines changed

4 files changed

+102
-0
lines changed

libraries/AP_HAL/CAN.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include "CAN.h"
2+
3+
void AP_HAL::CANDriver::register_receiver(uint8_t bus_mask, ReceiveCb cb) {
4+
if (_num_receivers == AP_HAL_CAN_MAX_RECEIVERS) {
5+
return;
6+
}
7+
8+
_receivers[_num_receivers].bus_mask = bus_mask;
9+
_receivers[_num_receivers].cb = cb;
10+
11+
_num_receivers++;
12+
}
13+
14+
void AP_HAL::CANDriver::process_message(uint32_t recv_time_us, const struct message_s& message)
15+
{
16+
for (uint8_t i=0; i<_num_receivers; i++) {
17+
if (_receivers[i].bus_mask & (1<<message.bus_id)) {
18+
_receivers[i].cb(recv_time_us, message);
19+
}
20+
}
21+
}
22+

libraries/AP_HAL/CAN.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#pragma once
2+
3+
#include <stdint.h>
4+
#include "AP_HAL_Namespace.h"
5+
#include "utility/functor.h"
6+
7+
#define AP_HAL_CAN_MAX_RECEIVERS 8
8+
9+
class AP_HAL::CANDriver {
10+
public:
11+
FUNCTOR_TYPEDEF(ReceiveCb, void, uint32_t, const struct message_s&);
12+
struct message_s {
13+
uint8_t bus_id;
14+
uint32_t id;
15+
uint8_t rtr : 1;
16+
uint8_t extid : 1;
17+
uint8_t length : 4;
18+
uint8_t data[8];
19+
};
20+
21+
void register_receiver(uint8_t bus_mask, ReceiveCb cb);
22+
23+
virtual bool transmit(const struct message_s& message) = 0;
24+
25+
protected:
26+
void process_message(uint32_t recv_time_us, const struct message_s& message);
27+
28+
private:
29+
struct receiver_s {
30+
uint8_t bus_mask;
31+
ReceiveCb cb;
32+
};
33+
34+
uint8_t _num_receivers;
35+
struct receiver_s _receivers[AP_HAL_CAN_MAX_RECEIVERS];
36+
};

libraries/CAN_Servo/CAN_Servo.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include "CAN_Servo.h"
2+
3+
extern const AP_HAL::HAL& hal;
4+
5+
CAN_Servo::CAN_Servo(uint8_t bus, uint32_t angle_command_id, uint32_t angle_feedback_id) :
6+
_angle_command_id(angle_command_id),
7+
_angle_feedback_id(angle_feedback_id),
8+
_bus(bus)
9+
{
10+
hal.can->register_receiver(1<<bus, FUNCTOR_BIND_MEMBER(can_recv, void, uint32_t, const struct AP_HAL::CAN::message_s&));
11+
}
12+
13+
void CAN_Servo::send_angle_target(float angle) {
14+
// TODO populate the message struct in AP_HAL::CAN::transmit, not here
15+
16+
struct AP_HAL::CAN::message_s msg;
17+
msg.bus_id = _bus;
18+
msg.id = _angle_command_id;
19+
msg.rtr = 0;
20+
msg.extid = 0;
21+
msg.length = 4;
22+
memcpy(msg.data, &angle, 4);
23+
hal.can->transmit(msg);
24+
}
25+
26+
void CAN_Servo::can_recv(uint32_t time_us, const struct AP_HAL::CAN::message_s& msg)
27+
{
28+
if (msg.id == _angle_feedback_id && msg.length == 4) {
29+
memcpy(&_angle, msg.data, 4);
30+
}
31+
}

libraries/CAN_Servo/CAN_Servo.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#include <AP_HAL/AP_HAL.h>
2+
3+
class CAN_Servo {
4+
public:
5+
CAN_Servo(uint8_t bus, uint32_t angle_command_id, uint32_t angle_feedback_id);
6+
void send_angle_target(float angle);
7+
private:
8+
void can_recv(uint32_t time_us, const struct AP_HAL::CAN::message_s& msg);
9+
float _angle;
10+
uint32_t _angle_command_id;
11+
uint32_t _angle_feedback_id;
12+
uint8_t _bus;
13+
};

0 commit comments

Comments
 (0)