Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 23 additions & 13 deletions main/modules/can.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ static uint32_t to_29_bit(const int64_t value, const std::string &what) {
return value;
}

// Lizard's own modules send in every step, so a stopped bus or a full TX queue would flood the console.
static void log_dropped_frame(const char *reason) {
static unsigned long last_drop_log = 0;
if (millis_since(last_drop_log) > 1000) {
echo("CAN send dropped: %s", reason);
last_drop_log = millis();
}
}

static Module_ptr create_can(const std::string &name, const std::vector<ConstExpression_ptr> &arguments, MessageHandler) {
Module::expect(arguments, 3, integer, integer, integer);
const gpio_num_t rx_pin = (gpio_num_t)arguments[0]->evaluate_integer();
Expand Down Expand Up @@ -173,19 +182,15 @@ bool Can::receive() {
return true;
}

void Can::send(const uint32_t id, const uint8_t data[8], const bool rtr, uint8_t dlc) const {
bool Can::send(const uint32_t id, const uint8_t data[8], const bool rtr, const uint8_t dlc) const {
if (id > MAX_EXTENDED_ID) {
throw std::runtime_error("CAN ID does not fit into 29 bits");
}

twai_status_info_t status_info;
if (twai_get_status_info(&status_info) != ESP_OK || status_info.state != TWAI_STATE_RUNNING) {
static unsigned long last_drop_log = 0;
if (millis_since(last_drop_log) > 1000) {
echo("CAN send dropped: bus not RUNNING");
last_drop_log = millis();
}
return;
log_dropped_frame("bus not RUNNING");
return false;
}

twai_message_t message;
Expand All @@ -197,15 +202,20 @@ void Can::send(const uint32_t id, const uint8_t data[8], const bool rtr, uint8_t
message.data[i] = data[i];
}

twai_transmit(&message, pdMS_TO_TICKS(0));
const esp_err_t result = twai_transmit(&message, pdMS_TO_TICKS(0));
if (result != ESP_OK) {
log_dropped_frame(result == ESP_ERR_TIMEOUT ? "TX queue full" : esp_err_to_name(result));
return false;
}
return true;
}

void Can::send(uint32_t id,
uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3,
uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7,
bool rtr) const {
bool Can::send(const uint32_t id,
const uint8_t d0, const uint8_t d1, const uint8_t d2, const uint8_t d3,
const uint8_t d4, const uint8_t d5, const uint8_t d6, const uint8_t d7,
const bool rtr) const {
uint8_t data[8] = {d0, d1, d2, d3, d4, d5, d6, d7};
this->send(id, data, rtr);
return this->send(id, data, rtr);
}

void Can::call(const std::string method_name, const std::vector<ConstExpression_ptr> arguments) {
Expand Down
6 changes: 4 additions & 2 deletions main/modules/can.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ class Can : public Module {
static const std::map<std::string, Variable_ptr> get_defaults();

bool receive();
void send(const uint32_t id, const uint8_t data[8], const bool rtr = false, const uint8_t dlc = 8) const;
void send(const uint32_t id,
// Both overloads return whether the driver accepted the frame, not whether it was acknowledged on the bus.
// false means the frame was dropped, because the bus is not RUNNING or the TX queue is full.
bool send(const uint32_t id, const uint8_t data[8], const bool rtr = false, const uint8_t dlc = 8) const;
bool send(const uint32_t id,
const uint8_t d0, const uint8_t d1, const uint8_t d2, const uint8_t d3,
const uint8_t d4, const uint8_t d5, const uint8_t d6, const uint8_t d7,
const bool rtr = false) const;
Expand Down
4 changes: 3 additions & 1 deletion main/modules/rmd_motor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ bool RmdMotor::send(const uint8_t d0, const uint8_t d1, const uint8_t d2, const
this->last_msg_id = 0;
const int max_attempts = 3;
for (int i = 0; i < max_attempts; ++i) {
this->can->send(this->motor_id + 0x140, d0, d1, d2, d3, d4, d5, d6, d7);
if (!this->can->send(this->motor_id + 0x140, d0, d1, d2, d3, d4, d5, d6, d7)) {
return false; // the bus is not RUNNING or the TX queue is full; the next step() sends again anyway
}
unsigned long int start = micros();
while (this->last_msg_id != d0 && micros_since(start) < timeout_ms * 1000) {
this->can->receive();
Expand Down
Loading