Skip to content

Commit

Permalink
DroneCAN: use TWAI acceptance filters
Browse files Browse the repository at this point in the history
this allows the ESP32 to cope with high rate traffic for DroneCAN ESCs
without choking. We use the priority field as a discriminator as the
TWAI acceptance filters are don't allow complex enough filters to work
on all the message IDs we need. We rely on the messages we want being
low priority
  • Loading branch information
tridge committed Oct 14, 2023
1 parent f5cf88d commit 74b5aa2
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 6 deletions.
11 changes: 7 additions & 4 deletions RemoteIDModule/CANDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,14 @@
CANDriver::CANDriver()
{}

void CANDriver::init(uint32_t bitrate)
static const twai_timing_config_t t_config = TWAI_TIMING_CONFIG_1MBITS();
static twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();

void CANDriver::init(uint32_t bitrate, uint32_t acceptance_code, uint32_t acceptance_mask)
{
f_config.acceptance_code = acceptance_code;
f_config.acceptance_mask = acceptance_mask;
f_config.single_filter = true;
init_bus(bitrate);
}

Expand All @@ -45,9 +51,6 @@ static const twai_general_config_t g_config = {.mode = TWAI
.intr_flags = ESP_INTR_FLAG_LEVEL2
};

static const twai_timing_config_t t_config = TWAI_TIMING_CONFIG_1MBITS();
static const twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();

void CANDriver::init_once(bool enable_irq)
{
if (twai_driver_install(&g_config, &t_config, &f_config) == ESP_OK)
Expand Down
2 changes: 1 addition & 1 deletion RemoteIDModule/CANDriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ struct CANFrame;
class CANDriver {
public:
CANDriver();
void init(uint32_t bitrate);
void init(uint32_t bitrate, uint32_t acceptance_code, uint32_t acceptance_mask);

bool send(const CANFrame &frame);
bool receive(CANFrame &out_frame);
Expand Down
20 changes: 19 additions & 1 deletion RemoteIDModule/DroneCAN.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,25 @@ void DroneCAN::init(void)
gpio_reset_pin(GPIO_NUM_20);
#endif

can_driver.init(1000000);
/*
the ESP32 has a very inefficient CAN (TWAI) stack. If we let it
receive all message types then when the bus is busy it will
spend all its time in processRx(). To cope we need to use
acceptance filters so we don't see most traffic. Unfortunately
the ESP32 has a very rudimentary acceptance filter system which
cannot be setup to block the high rate messages (such as ESC
commands) while still allowing all of the RemoteID messages we
need. The best we can do is use the message priority. The high
rate messages all have a low valued priority number (which means
a high priority). So by setting a single bit acceptance code in
the top bit of the 3 bit priority field we only see messages
that have a priority number of 16 or higher (which means
CANARD_TRANSFER_PRIORITY_MEDIUM or lower priority)
*/
const uint32_t acceptance_code = 0x10000000U<<3;
const uint32_t acceptance_mask = 0x0FFFFFFFU<<3;

can_driver.init(1000000, acceptance_code, acceptance_mask);

canardInit(&canard, (uint8_t *)canard_memory_pool, sizeof(canard_memory_pool),
onTransferReceived_trampoline, shouldAcceptTransfer_trampoline, NULL);
Expand Down

0 comments on commit 74b5aa2

Please sign in to comment.