From 6a99af9b6c22c003a34b32f0512224dff65ba82e Mon Sep 17 00:00:00 2001 From: Piotr Mikulowski Date: Wed, 3 May 2023 18:24:58 +0100 Subject: [PATCH 1/7] Add ID List CAN ID Filter in rtcan_start() --- src/rtcan.c | 68 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 48 insertions(+), 20 deletions(-) diff --git a/src/rtcan.c b/src/rtcan.c index 78453b7..13f5a46 100644 --- a/src/rtcan.c +++ b/src/rtcan.c @@ -179,26 +179,6 @@ rtcan_status_t rtcan_init(rtcan_handle_t* rtcan_h, ADD_ERROR_IF(tx_status != TX_SUCCESS, RTCAN_ERROR_INTERNAL, rtcan_h); } - // TODO: configure CAN filters - if (no_errors(rtcan_h)) - { - CAN_FilterTypeDef filter; - filter.FilterActivation = ENABLE; - filter.FilterFIFOAssignment = CAN_FILTER_FIFO0; - filter.FilterIdHigh = 0x0000 << 5U; - filter.FilterIdLow = 0x0000 << 5U; - filter.FilterMaskIdHigh = 0x0000 << 5U; - filter.FilterMaskIdLow = 0x0000 << 5U; - filter.FilterMode = CAN_FILTERMODE_IDMASK; - filter.FilterScale = CAN_FILTERSCALE_16BIT; - filter.FilterBank = 0; - - HAL_StatusTypeDef hal_status = HAL_CAN_ConfigFilter(rtcan_h->hcan, - &filter); - - ADD_ERROR_IF(hal_status != HAL_OK, RTCAN_ERROR_INIT, rtcan_h); - } - return create_status(rtcan_h); } @@ -209,6 +189,54 @@ rtcan_status_t rtcan_init(rtcan_handle_t* rtcan_h, */ rtcan_status_t rtcan_start(rtcan_handle_t* rtcan_h) { + /* Since the subscriber ID list is known, we can configure the CAN ID Filter now */ + + uint32_t can_id_list[RTCAN_HASHMAP_SIZE] = {0}; + int number_ids = 0; + + /* Save and count all CAN IDs stored in hashmap */ + for (uint32_t i = 0; i < RTCAN_HASHMAP_SIZE; i++) + { + if(rtcan_h->subscriber_map[i] != NULL) + { + /* CAN ID found! */ + can_id_list[number_ids] = rtcan_h->subscriber_map[i]->can_id; + number_ids++; + + } + } + + int number_banks = (number_ids-1)/4 + 1; + + /* Error if there's too many ids to apply filter */ + ADD_ERROR_IF(number_banks > 28, RTCAN_ERROR_INIT, rtcan_h); + + if (no_errors(rtcan_h)) + { + CAN_FilterTypeDef filter; + filter.FilterActivation = ENABLE; + filter.FilterFIFOAssignment = CAN_FILTER_FIFO0; + filter.FilterMode = CAN_FILTERMODE_IDLIST; + filter.FilterScale = CAN_FILTERSCALE_16BIT; + + /* Configure Filter IDs for each filter */ + for(int i = 0; i < number_banks; i++) + { + filter.FilterIdHigh = can_id_list[4 * i] << 5U; + filter.FilterIdLow = can_id_list[4 * i + 1] << 5U; + filter.FilterMaskIdHigh = can_id_list[4 * i + 2] << 5U; + filter.FilterMaskIdLow = can_id_list[4 * i + 3] << 5U; + filter.FilterBank = i; + + + HAL_StatusTypeDef hal_status = HAL_CAN_ConfigFilter(rtcan_h->hcan, + &filter); + + ADD_ERROR_IF(hal_status != HAL_OK, RTCAN_ERROR_INIT, rtcan_h); + } + } + + TX_THREAD* threads[2] = {&rtcan_h->tx_thread, &rtcan_h->rx_thread}; for (uint32_t i = 0; i < 2; i++) From f46f187f35a352ae5ba1b7f83cfc490d9522be57 Mon Sep 17 00:00:00 2001 From: Piotr Mikulowski Date: Wed, 3 May 2023 18:41:42 +0100 Subject: [PATCH 2/7] Fix comments --- src/rtcan.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/rtcan.c b/src/rtcan.c index 13f5a46..e6ee189 100644 --- a/src/rtcan.c +++ b/src/rtcan.c @@ -199,7 +199,7 @@ rtcan_status_t rtcan_start(rtcan_handle_t* rtcan_h) { if(rtcan_h->subscriber_map[i] != NULL) { - /* CAN ID found! */ + /* Subscriber found! */ can_id_list[number_ids] = rtcan_h->subscriber_map[i]->can_id; number_ids++; @@ -219,7 +219,7 @@ rtcan_status_t rtcan_start(rtcan_handle_t* rtcan_h) filter.FilterMode = CAN_FILTERMODE_IDLIST; filter.FilterScale = CAN_FILTERSCALE_16BIT; - /* Configure Filter IDs for each filter */ + /* Configure Filter IDs for each filter bank */ for(int i = 0; i < number_banks; i++) { filter.FilterIdHigh = can_id_list[4 * i] << 5U; From b555b35819ba813275e317aa622fdc33323d848a Mon Sep 17 00:00:00 2001 From: Piotr Mikulowski Date: Wed, 3 May 2023 20:09:31 +0100 Subject: [PATCH 3/7] Add constants, for each hash entry look for chained nodes --- src/rtcan.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/rtcan.c b/src/rtcan.c index e6ee189..dccfc21 100644 --- a/src/rtcan.c +++ b/src/rtcan.c @@ -15,6 +15,8 @@ * thread constants */ #define RTCAN_THREAD_STACK_SIZE 1024 // TODO: this needs to be profiled +#define NUM_FILTERS 28 +#define NUM_IDS_PER_FILTER 4 /* * useful macros @@ -191,25 +193,34 @@ rtcan_status_t rtcan_start(rtcan_handle_t* rtcan_h) { /* Since the subscriber ID list is known, we can configure the CAN ID Filter now */ - uint32_t can_id_list[RTCAN_HASHMAP_SIZE] = {0}; + uint32_t can_id_list[NUM_FILTERS * NUM_IDS_PER_FILTER] = {0}; int number_ids = 0; /* Save and count all CAN IDs stored in hashmap */ for (uint32_t i = 0; i < RTCAN_HASHMAP_SIZE; i++) { - if(rtcan_h->subscriber_map[i] != NULL) + rtcan_hashmap_node_t* node = rtcan_h->subscriber_map[i]; + if(node != NULL) { /* Subscriber found! */ - can_id_list[number_ids] = rtcan_h->subscriber_map[i]->can_id; + can_id_list[number_ids] = node->can_id; number_ids++; + + while(node->chained_node_ptr != NULL) + { + /* Chained node found! */ + node = node->chained_node_ptr; + can_id_list[number_ids] = node->can_id; + number_ids++; + } } } - int number_banks = (number_ids-1)/4 + 1; + int number_banks = (number_ids-1)/NUM_IDS_PER_FILTER + 1; /* Error if there's too many ids to apply filter */ - ADD_ERROR_IF(number_banks > 28, RTCAN_ERROR_INIT, rtcan_h); + ADD_ERROR_IF(number_banks > NUM_FILTERS, RTCAN_ERROR_INIT, rtcan_h); if (no_errors(rtcan_h)) { @@ -222,10 +233,10 @@ rtcan_status_t rtcan_start(rtcan_handle_t* rtcan_h) /* Configure Filter IDs for each filter bank */ for(int i = 0; i < number_banks; i++) { - filter.FilterIdHigh = can_id_list[4 * i] << 5U; - filter.FilterIdLow = can_id_list[4 * i + 1] << 5U; - filter.FilterMaskIdHigh = can_id_list[4 * i + 2] << 5U; - filter.FilterMaskIdLow = can_id_list[4 * i + 3] << 5U; + filter.FilterIdHigh = can_id_list[NUM_IDS_PER_FILTER * i] << 5U; + filter.FilterIdLow = can_id_list[NUM_IDS_PER_FILTER * i + 1] << 5U; + filter.FilterMaskIdHigh = can_id_list[NUM_IDS_PER_FILTER * i + 2] << 5U; + filter.FilterMaskIdLow = can_id_list[NUM_IDS_PER_FILTER * i + 3] << 5U; filter.FilterBank = i; From 9e4126c078794e92ef9095c5750dae55cd07753e Mon Sep 17 00:00:00 2001 From: Piotr Mikulowski Date: Thu, 4 May 2023 19:02:44 +0100 Subject: [PATCH 4/7] Alternate filter assignment between both FIFOs --- src/rtcan.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/rtcan.c b/src/rtcan.c index dccfc21..866bd2c 100644 --- a/src/rtcan.c +++ b/src/rtcan.c @@ -226,7 +226,6 @@ rtcan_status_t rtcan_start(rtcan_handle_t* rtcan_h) { CAN_FilterTypeDef filter; filter.FilterActivation = ENABLE; - filter.FilterFIFOAssignment = CAN_FILTER_FIFO0; filter.FilterMode = CAN_FILTERMODE_IDLIST; filter.FilterScale = CAN_FILTERSCALE_16BIT; @@ -238,7 +237,16 @@ rtcan_status_t rtcan_start(rtcan_handle_t* rtcan_h) filter.FilterMaskIdHigh = can_id_list[NUM_IDS_PER_FILTER * i + 2] << 5U; filter.FilterMaskIdLow = can_id_list[NUM_IDS_PER_FILTER * i + 3] << 5U; filter.FilterBank = i; - + + /* Alternate between FIFO0 and FIFO1 to share the load evenly */ + if(i % 2) + { + filter.FilterFIFOAssignment = CAN_FILTER_FIFO1; + } + else + { + filter.FilterFIFOAssignment = CAN_FILTER_FIFO0; + } HAL_StatusTypeDef hal_status = HAL_CAN_ConfigFilter(rtcan_h->hcan, &filter); From 3008cd31ab673903dba90f58a28c2af2ee8e99c3 Mon Sep 17 00:00:00 2001 From: Piotr Mikulowski Date: Thu, 4 May 2023 19:06:55 +0100 Subject: [PATCH 5/7] Add limit (NUM_FILTERS * NUM_IDS_PER_FILTER) to the can id finder loop --- src/rtcan.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/rtcan.c b/src/rtcan.c index 866bd2c..4d2ccd6 100644 --- a/src/rtcan.c +++ b/src/rtcan.c @@ -205,6 +205,10 @@ rtcan_status_t rtcan_start(rtcan_handle_t* rtcan_h) /* Subscriber found! */ can_id_list[number_ids] = node->can_id; number_ids++; + if(number_ids > (NUM_FILTERS * NUM_IDS_PER_FILTER)) + { + break; + } while(node->chained_node_ptr != NULL) { @@ -212,6 +216,10 @@ rtcan_status_t rtcan_start(rtcan_handle_t* rtcan_h) node = node->chained_node_ptr; can_id_list[number_ids] = node->can_id; number_ids++; + if(number_ids > (NUM_FILTERS * NUM_IDS_PER_FILTER)) + { + break; + } } } @@ -237,7 +245,7 @@ rtcan_status_t rtcan_start(rtcan_handle_t* rtcan_h) filter.FilterMaskIdHigh = can_id_list[NUM_IDS_PER_FILTER * i + 2] << 5U; filter.FilterMaskIdLow = can_id_list[NUM_IDS_PER_FILTER * i + 3] << 5U; filter.FilterBank = i; - + /* Alternate between FIFO0 and FIFO1 to share the load evenly */ if(i % 2) { From ae80c5e2916ba26a86d330fc26a9e862f9924209 Mon Sep 17 00:00:00 2001 From: Piotr Mikulowski Date: Wed, 10 May 2023 22:25:54 +0100 Subject: [PATCH 6/7] Move the filter configuration to rtcan_subscribe() --- inc/rtcan.h | 10 +++++ src/rtcan.c | 123 ++++++++++++++++++++++------------------------------ 2 files changed, 61 insertions(+), 72 deletions(-) diff --git a/inc/rtcan.h b/inc/rtcan.h index a7872bc..145d9f5 100644 --- a/inc/rtcan.h +++ b/inc/rtcan.h @@ -215,6 +215,16 @@ typedef struct */ atomic_bool rx_ready; + /** + * @brief Current subscriber number + */ + uint32_t subscriber_number; + + /** + * @brief Variable that holds 4 consecutive can_ids for filter bank configuration + */ + uint32_t can_ids[4]; + } rtcan_handle_t; /* diff --git a/src/rtcan.c b/src/rtcan.c index 4d2ccd6..22e0c8d 100644 --- a/src/rtcan.c +++ b/src/rtcan.c @@ -60,6 +60,12 @@ rtcan_status_t rtcan_init(rtcan_handle_t* rtcan_h, rtcan_h->err = RTCAN_ERROR_NONE; atomic_store(&rtcan_h->rx_ready, true); + rtcan_h->subscriber_number = 0; + for(int i = 0; i <4 ; i++) + { + rtcan_h->can_ids[i] = 0; + } + // threads void* stack_ptr = NULL; @@ -191,78 +197,6 @@ rtcan_status_t rtcan_init(rtcan_handle_t* rtcan_h, */ rtcan_status_t rtcan_start(rtcan_handle_t* rtcan_h) { - /* Since the subscriber ID list is known, we can configure the CAN ID Filter now */ - - uint32_t can_id_list[NUM_FILTERS * NUM_IDS_PER_FILTER] = {0}; - int number_ids = 0; - - /* Save and count all CAN IDs stored in hashmap */ - for (uint32_t i = 0; i < RTCAN_HASHMAP_SIZE; i++) - { - rtcan_hashmap_node_t* node = rtcan_h->subscriber_map[i]; - if(node != NULL) - { - /* Subscriber found! */ - can_id_list[number_ids] = node->can_id; - number_ids++; - if(number_ids > (NUM_FILTERS * NUM_IDS_PER_FILTER)) - { - break; - } - - while(node->chained_node_ptr != NULL) - { - /* Chained node found! */ - node = node->chained_node_ptr; - can_id_list[number_ids] = node->can_id; - number_ids++; - if(number_ids > (NUM_FILTERS * NUM_IDS_PER_FILTER)) - { - break; - } - } - - } - } - - int number_banks = (number_ids-1)/NUM_IDS_PER_FILTER + 1; - - /* Error if there's too many ids to apply filter */ - ADD_ERROR_IF(number_banks > NUM_FILTERS, RTCAN_ERROR_INIT, rtcan_h); - - if (no_errors(rtcan_h)) - { - CAN_FilterTypeDef filter; - filter.FilterActivation = ENABLE; - filter.FilterMode = CAN_FILTERMODE_IDLIST; - filter.FilterScale = CAN_FILTERSCALE_16BIT; - - /* Configure Filter IDs for each filter bank */ - for(int i = 0; i < number_banks; i++) - { - filter.FilterIdHigh = can_id_list[NUM_IDS_PER_FILTER * i] << 5U; - filter.FilterIdLow = can_id_list[NUM_IDS_PER_FILTER * i + 1] << 5U; - filter.FilterMaskIdHigh = can_id_list[NUM_IDS_PER_FILTER * i + 2] << 5U; - filter.FilterMaskIdLow = can_id_list[NUM_IDS_PER_FILTER * i + 3] << 5U; - filter.FilterBank = i; - - /* Alternate between FIFO0 and FIFO1 to share the load evenly */ - if(i % 2) - { - filter.FilterFIFOAssignment = CAN_FILTER_FIFO1; - } - else - { - filter.FilterFIFOAssignment = CAN_FILTER_FIFO0; - } - - HAL_StatusTypeDef hal_status = HAL_CAN_ConfigFilter(rtcan_h->hcan, - &filter); - - ADD_ERROR_IF(hal_status != HAL_OK, RTCAN_ERROR_INIT, rtcan_h); - } - } - TX_THREAD* threads[2] = {&rtcan_h->tx_thread, &rtcan_h->rx_thread}; @@ -621,6 +555,51 @@ rtcan_status_t rtcan_subscribe(rtcan_handle_t* rtcan_h, } } + /* Add subscriber's CAN ID to CAN filter ID List */ + + int bank_number = rtcan_h->subscriber_number / NUM_IDS_PER_FILTER + 1; // Calculate the current filter bank number + + /* We need to store 4 consecutive can_ids to setup filter bank. + Otherwise, it overwrites the previous filter configuration deleting previous can_ids */ + + int k = rtcan_h->subscriber_number % NUM_IDS_PER_FILTER ; //Calculate index of element in can_ids table + rtcan_h->can_ids[k] = can_id; + + rtcan_h->subscriber_number++; // Increment subscriber counter + ADD_ERROR_IF(bank_number > NUM_FILTERS, RTCAN_ERROR_INIT, rtcan_h); + + if (no_errors(rtcan_h)) + { + CAN_FilterTypeDef filter; + filter.FilterActivation = ENABLE; + filter.FilterMode = CAN_FILTERMODE_IDLIST; + filter.FilterScale = CAN_FILTERSCALE_16BIT; + + /* Configure Filter IDs for each filter bank */ + + filter.FilterIdHigh = can_ids[0] << 5U; + filter.FilterIdLow = can_ids[1] << 5U; + filter.FilterMaskIdHigh = can_ids[2] << 5U; + filter.FilterMaskIdLow = can_ids[3] << 5U; + filter.FilterBank = bank_number; + + /* Alternate between FIFO0 and FIFO1 to share the load evenly */ + if(bank_number % 2) + { + filter.FilterFIFOAssignment = CAN_FILTER_FIFO1; + } + else + { + filter.FilterFIFOAssignment = CAN_FILTER_FIFO0; + } + + HAL_StatusTypeDef hal_status = HAL_CAN_ConfigFilter(rtcan_h->hcan, + &filter); + + ADD_ERROR_IF(hal_status != HAL_OK, RTCAN_ERROR_INIT, rtcan_h); + + } + return create_status(rtcan_h); } From aaf21fda6a99ace4b50a28101af52977dafe23ce Mon Sep 17 00:00:00 2001 From: Piotr Mikulowski Date: Wed, 10 May 2023 22:28:46 +0100 Subject: [PATCH 7/7] Fix can_ids --- inc/rtcan.h | 2 +- src/rtcan.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/inc/rtcan.h b/inc/rtcan.h index 145d9f5..48b7c87 100644 --- a/inc/rtcan.h +++ b/inc/rtcan.h @@ -221,7 +221,7 @@ typedef struct uint32_t subscriber_number; /** - * @brief Variable that holds 4 consecutive can_ids for filter bank configuration + * @brief Table that holds 4 consecutive can_ids for filter bank configuration */ uint32_t can_ids[4]; diff --git a/src/rtcan.c b/src/rtcan.c index 22e0c8d..98a1b8e 100644 --- a/src/rtcan.c +++ b/src/rtcan.c @@ -577,10 +577,10 @@ rtcan_status_t rtcan_subscribe(rtcan_handle_t* rtcan_h, /* Configure Filter IDs for each filter bank */ - filter.FilterIdHigh = can_ids[0] << 5U; - filter.FilterIdLow = can_ids[1] << 5U; - filter.FilterMaskIdHigh = can_ids[2] << 5U; - filter.FilterMaskIdLow = can_ids[3] << 5U; + filter.FilterIdHigh = rtcan_h->can_ids[0] << 5U; + filter.FilterIdLow = rtcan_h->can_ids[1] << 5U; + filter.FilterMaskIdHigh = rtcan_h->can_ids[2] << 5U; + filter.FilterMaskIdLow = rtcan_h->can_ids[3] << 5U; filter.FilterBank = bank_number; /* Alternate between FIFO0 and FIFO1 to share the load evenly */