Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix extended CAN filters #857

Merged
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
21 changes: 16 additions & 5 deletions hal/src/stm32f2xx/can_hal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -760,11 +760,22 @@ bool CANDriver::addFilter(uint32_t id, uint32_t mask, HAL_CAN_Filters type)
return false;
}

// Filter configuration - Register organization
// Lowest 11 bits of id are first, then next 18 bits of id, then
// standard/extended bit, then RTR bit, then 1 zero bit
uint32_t filterId = (id << 21) | ((id >> 8) & 0x1FFFF8) | (type == CAN_FILTER_EXTENDED ? 0x4 : 0);
uint32_t filterMask = (mask << 21) | ((mask >> 8) & 0x1FFFF8) | 0x6;
// Filter configuration
// See STM32F2 Reference Manual for register organization
uint32_t filterId, filterMask;
const uint32_t extendedBit = 0x4;
const uint32_t rtrBit = 0x2;

if(type == CAN_FILTER_STANDARD)
{
filterId = id << 21;
filterMask = (mask << 21) | extendedBit | rtrBit;
}
else
{
filterId = (id << 3) | extendedBit;
filterMask = (mask << 3) | extendedBit | rtrBit;
}

CAN_FilterInitTypeDef CAN_FilterInitStructure = {};
CAN_FilterInitStructure.CAN_FilterNumber = nextFilter;
Expand Down
174 changes: 168 additions & 6 deletions user/tests/wiring/no_fixture/can.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

#ifdef HAL_HAS_CAN_D1_D2

test(CAN_D1D2_ReceivesTransmittedMessage) {
test(CAN_D1_D2_ReceivesTransmittedMessage) {
CANChannel can(CAN_D1_D2);
can.begin(500000, CAN_TEST_MODE);

Expand All @@ -48,10 +48,29 @@ test(CAN_D1D2_ReceivesTransmittedMessage) {
assertEqual(rx.data[0], 10);
}

test(CAN_D1D2_DoesntReceiveFilteredMessage) {
test(CAN_D1_D2_ReceivesAcceptedMessage) {
CANChannel can(CAN_D1_D2);
can.begin(500000, CAN_TEST_MODE);
// Accept only message 0x100
// Accept only standard message 0x100
can.addFilter(0x100, 0x7FF);

CANMessage tx;
tx.id = 0x100;
tx.len = 1;
tx.data[0] = 10;
can.transmit(tx);
delay(1);
CANMessage rx;
bool hasMessage = can.receive(rx);
can.end();

assertEqual(hasMessage, true);
}

test(CAN_D1_D2_DoesntReceiveFilteredMessage) {
CANChannel can(CAN_D1_D2);
can.begin(500000, CAN_TEST_MODE);
// Accept only standard message 0x100
can.addFilter(0x100, 0x7FF);

CANMessage tx;
Expand All @@ -67,11 +86,73 @@ test(CAN_D1D2_DoesntReceiveFilteredMessage) {
assertEqual(hasMessage, false);
}

test(CAN_D1_D2_ReceivesTransmittedExtendedMessage) {
CANChannel can(CAN_D1_D2);
can.begin(500000, CAN_TEST_MODE);

CANMessage tx;
tx.extended = true;
tx.id = 0x3000;
tx.len = 1;
tx.data[0] = 10;
can.transmit(tx);
delay(1);
CANMessage rx;
bool hasMessage = can.receive(rx);
can.end();

assertEqual(hasMessage, true);
assertEqual(rx.extended, true);
assertEqual(rx.id, 0x3000);
assertEqual(rx.len, 1);
assertEqual(rx.data[0], 10);
}

test(CAN_D1_D2_ReceivesAcceptedExtendedMessage) {
CANChannel can(CAN_D1_D2);
can.begin(500000, CAN_TEST_MODE);
// Accept only extended message 0x3000
can.addFilter(0x3000, 0x7FF, CAN_FILTER_EXTENDED);

CANMessage tx;
tx.extended = true;
tx.id = 0x3000;
tx.len = 1;
tx.data[0] = 10;
can.transmit(tx);
delay(1);
CANMessage rx;
bool hasMessage = can.receive(rx);
can.end();

assertEqual(hasMessage, true);
}

test(CAN_D1_D2_DoesntReceiveFilteredExtendedMessage) {
CANChannel can(CAN_D1_D2);
can.begin(500000, CAN_TEST_MODE);
// Accept only extended message 0x3000
can.addFilter(0x3000, 0x7FF, CAN_FILTER_EXTENDED);

CANMessage tx;
tx.extended = true;
tx.id = 0x3001;
tx.len = 1;
tx.data[0] = 10;
can.transmit(tx);
delay(1);
CANMessage rx;
bool hasMessage = can.receive(rx);
can.end();

assertEqual(hasMessage, false);
}

#endif // HAL_HAS_CAN_D1_D2

#ifdef HAL_HAS_CAN_C4_C5

test(CAN_C4C5_ReceivesTransmittedMessage) {
test(CAN_C4_C5_ReceivesTransmittedMessage) {
CANChannel can(CAN_C4_C5);
can.begin(500000, CAN_TEST_MODE);

Expand All @@ -91,10 +172,29 @@ test(CAN_C4C5_ReceivesTransmittedMessage) {
assertEqual(rx.data[0], 10);
}

test(CAN_C4C5_DoesntReceiveFilteredMessage) {
test(CAN_C4_C5_ReceivesAcceptedMessage) {
CANChannel can(CAN_C4_C5);
can.begin(500000, CAN_TEST_MODE);
// Accept only message 0x100
// Accept only standard message 0x100
can.addFilter(0x100, 0x7FF);

CANMessage tx;
tx.id = 0x100;
tx.len = 1;
tx.data[0] = 10;
can.transmit(tx);
delay(1);
CANMessage rx;
bool hasMessage = can.receive(rx);
can.end();

assertEqual(hasMessage, true);
}

test(CAN_C4_C5_DoesntReceiveFilteredMessage) {
CANChannel can(CAN_C4_C5);
can.begin(500000, CAN_TEST_MODE);
// Accept only standard message 0x100
can.addFilter(0x100, 0x7FF);

CANMessage tx;
Expand All @@ -110,4 +210,66 @@ test(CAN_C4C5_DoesntReceiveFilteredMessage) {
assertEqual(hasMessage, false);
}

test(CAN_C4_C5_ReceivesTransmittedExtendedMessage) {
CANChannel can(CAN_C4_C5);
can.begin(500000, CAN_TEST_MODE);

CANMessage tx;
tx.extended = true;
tx.id = 0x3000;
tx.len = 1;
tx.data[0] = 10;
can.transmit(tx);
delay(1);
CANMessage rx;
bool hasMessage = can.receive(rx);
can.end();

assertEqual(hasMessage, true);
assertEqual(rx.extended, true);
assertEqual(rx.id, 0x3000);
assertEqual(rx.len, 1);
assertEqual(rx.data[0], 10);
}

test(CAN_C4_C5_ReceivesAcceptedExtendedMessage) {
CANChannel can(CAN_C4_C5);
can.begin(500000, CAN_TEST_MODE);
// Accept only extended message 0x3000
can.addFilter(0x3000, 0x7FF, CAN_FILTER_EXTENDED);

CANMessage tx;
tx.extended = true;
tx.id = 0x3000;
tx.len = 1;
tx.data[0] = 10;
can.transmit(tx);
delay(1);
CANMessage rx;
bool hasMessage = can.receive(rx);
can.end();

assertEqual(hasMessage, true);
}

test(CAN_C4_C5_DoesntReceiveFilteredExtendedMessage) {
CANChannel can(CAN_C4_C5);
can.begin(500000, CAN_TEST_MODE);
// Accept only extended message 0x3000
can.addFilter(0x3000, 0x7FF, CAN_FILTER_EXTENDED);

CANMessage tx;
tx.extended = true;
tx.id = 0x3001;
tx.len = 1;
tx.data[0] = 10;
can.transmit(tx);
delay(1);
CANMessage rx;
bool hasMessage = can.receive(rx);
can.end();

assertEqual(hasMessage, false);
}

#endif // HAL_HAS_CAN_C4_C5