drivers: can: stm32: naming clean-up
Namespace local functions, enums, structs and defines with stm32/STM32 to distinguish them from global CAN API. Also rename some internal conversion functions to make their meaning more clear and delete unused defines. Signed-off-by: Martin Jäger <martin@libre.solar>
This commit is contained in:
parent
d7c2a97fc5
commit
3524958083
2 changed files with 128 additions and 146 deletions
|
@ -44,11 +44,11 @@ LOG_MODULE_REGISTER(can_stm32, CONFIG_CAN_LOG_LEVEL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Translation tables
|
* Translation tables
|
||||||
* filter_in_bank[enum can_filter_type] = number of filters in bank for this type
|
* max_filters_per_bank[enum can_stm32_filter_type] = number of filters in bank for this type
|
||||||
* reg_demand[enum can_filter_type] = how many registers are used for this type
|
* filter_reg_demand[enum can_stm32_filter_type] = how many registers are used for this type
|
||||||
*/
|
*/
|
||||||
static const uint8_t filter_in_bank[] = {2, 4, 1, 2};
|
static const uint8_t max_filters_per_bank[] = {2, 4, 1, 2};
|
||||||
static const uint8_t reg_demand[] = {2, 1, 4, 2};
|
static const uint8_t filter_reg_demand[] = {2, 1, 4, 2};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Mutex to prevent simultaneous access to filter registers shared between CAN1
|
* Mutex to prevent simultaneous access to filter registers shared between CAN1
|
||||||
|
@ -56,7 +56,7 @@ static const uint8_t reg_demand[] = {2, 1, 4, 2};
|
||||||
*/
|
*/
|
||||||
static struct k_mutex filter_mutex;
|
static struct k_mutex filter_mutex;
|
||||||
|
|
||||||
static void can_stm32_signal_tx_complete(const struct device *dev, struct can_mailbox *mb)
|
static void can_stm32_signal_tx_complete(const struct device *dev, struct can_stm32_mailbox *mb)
|
||||||
{
|
{
|
||||||
if (mb->tx_callback) {
|
if (mb->tx_callback) {
|
||||||
mb->tx_callback(dev, mb->error, mb->callback_arg);
|
mb->tx_callback(dev, mb->error, mb->callback_arg);
|
||||||
|
@ -65,8 +65,7 @@ static void can_stm32_signal_tx_complete(const struct device *dev, struct can_ma
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void can_stm32_get_msg_fifo(CAN_FIFOMailBox_TypeDef *mbox,
|
static void can_stm32_rx_fifo_pop(CAN_FIFOMailBox_TypeDef *mbox, struct zcan_frame *frame)
|
||||||
struct zcan_frame *frame)
|
|
||||||
{
|
{
|
||||||
if (mbox->RIR & CAN_RI0R_IDE) {
|
if (mbox->RIR & CAN_RI0R_IDE) {
|
||||||
frame->id = mbox->RIR >> CAN_RI0R_EXID_Pos;
|
frame->id = mbox->RIR >> CAN_RI0R_EXID_Pos;
|
||||||
|
@ -105,7 +104,7 @@ static inline void can_stm32_rx_isr_handler(const struct device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DBG("Message on filter index %d", filter_match_index);
|
LOG_DBG("Message on filter index %d", filter_match_index);
|
||||||
can_stm32_get_msg_fifo(mbox, &frame);
|
can_stm32_rx_fifo_pop(mbox, &frame);
|
||||||
|
|
||||||
callback = data->rx_cb[filter_match_index];
|
callback = data->rx_cb[filter_match_index];
|
||||||
|
|
||||||
|
@ -293,7 +292,7 @@ static void can_stm32_state_change_isr(const struct device *dev)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int can_enter_init_mode(CAN_TypeDef *can)
|
static int can_stm32_enter_init_mode(CAN_TypeDef *can)
|
||||||
{
|
{
|
||||||
uint32_t start_time;
|
uint32_t start_time;
|
||||||
|
|
||||||
|
@ -310,7 +309,7 @@ static int can_enter_init_mode(CAN_TypeDef *can)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int can_leave_init_mode(CAN_TypeDef *can)
|
static int can_stm32_leave_init_mode(CAN_TypeDef *can)
|
||||||
{
|
{
|
||||||
uint32_t start_time;
|
uint32_t start_time;
|
||||||
|
|
||||||
|
@ -326,7 +325,7 @@ static int can_leave_init_mode(CAN_TypeDef *can)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int can_leave_sleep_mode(CAN_TypeDef *can)
|
static int can_stm32_leave_sleep_mode(CAN_TypeDef *can)
|
||||||
{
|
{
|
||||||
uint32_t start_time;
|
uint32_t start_time;
|
||||||
|
|
||||||
|
@ -375,7 +374,7 @@ static int can_stm32_set_mode(const struct device *dev, can_mode_t mode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = can_enter_init_mode(can);
|
ret = can_stm32_enter_init_mode(can);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
LOG_ERR("Failed to enter init mode");
|
LOG_ERR("Failed to enter init mode");
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -403,7 +402,7 @@ static int can_stm32_set_mode(const struct device *dev, can_mode_t mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
ret = can_leave_init_mode(can);
|
ret = can_stm32_leave_init_mode(can);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
LOG_ERR("Failed to leave init mode");
|
LOG_ERR("Failed to leave init mode");
|
||||||
|
|
||||||
|
@ -427,7 +426,7 @@ static int can_stm32_set_timing(const struct device *dev,
|
||||||
int ret = -EIO;
|
int ret = -EIO;
|
||||||
|
|
||||||
k_mutex_lock(&data->inst_mutex, K_FOREVER);
|
k_mutex_lock(&data->inst_mutex, K_FOREVER);
|
||||||
ret = can_enter_init_mode(can);
|
ret = can_stm32_enter_init_mode(can);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
LOG_ERR("Failed to enter init mode");
|
LOG_ERR("Failed to enter init mode");
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -443,7 +442,7 @@ static int can_stm32_set_timing(const struct device *dev,
|
||||||
(((timing->sjw - 1) << CAN_BTR_SJW_Pos) & CAN_BTR_SJW_Msk);
|
(((timing->sjw - 1) << CAN_BTR_SJW_Pos) & CAN_BTR_SJW_Msk);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = can_leave_init_mode(can);
|
ret = can_stm32_leave_init_mode(can);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
LOG_ERR("Failed to leave init mode");
|
LOG_ERR("Failed to leave init mode");
|
||||||
} else {
|
} else {
|
||||||
|
@ -504,7 +503,7 @@ static int can_stm32_init(const struct device *dev)
|
||||||
data->state_change_cb = NULL;
|
data->state_change_cb = NULL;
|
||||||
data->state_change_cb_data = NULL;
|
data->state_change_cb_data = NULL;
|
||||||
|
|
||||||
data->filter_usage = (1ULL << CAN_MAX_NUMBER_OF_FILTERS) - 1ULL;
|
data->filter_usage = (1ULL << CAN_STM32_MAX_NUM_FILTERS) - 1ULL;
|
||||||
(void)memset(data->rx_cb, 0, sizeof(data->rx_cb));
|
(void)memset(data->rx_cb, 0, sizeof(data->rx_cb));
|
||||||
(void)memset(data->cb_arg, 0, sizeof(data->cb_arg));
|
(void)memset(data->cb_arg, 0, sizeof(data->cb_arg));
|
||||||
|
|
||||||
|
@ -530,13 +529,13 @@ static int can_stm32_init(const struct device *dev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = can_leave_sleep_mode(can);
|
ret = can_stm32_leave_sleep_mode(can);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
LOG_ERR("Failed to exit sleep mode");
|
LOG_ERR("Failed to exit sleep mode");
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = can_enter_init_mode(can);
|
ret = can_stm32_enter_init_mode(can);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
LOG_ERR("Failed to enter init mode");
|
LOG_ERR("Failed to enter init mode");
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -624,12 +623,12 @@ static int can_stm32_recover(const struct device *dev, k_timeout_t timeout)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = can_enter_init_mode(can);
|
ret = can_stm32_enter_init_mode(can);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
can_leave_init_mode(can);
|
can_stm32_leave_init_mode(can);
|
||||||
|
|
||||||
start_time = k_uptime_ticks();
|
start_time = k_uptime_ticks();
|
||||||
|
|
||||||
|
@ -658,7 +657,7 @@ static int can_stm32_send(const struct device *dev, const struct zcan_frame *fra
|
||||||
CAN_TypeDef *can = cfg->can;
|
CAN_TypeDef *can = cfg->can;
|
||||||
uint32_t transmit_status_register = can->TSR;
|
uint32_t transmit_status_register = can->TSR;
|
||||||
CAN_TxMailBox_TypeDef *mailbox = NULL;
|
CAN_TxMailBox_TypeDef *mailbox = NULL;
|
||||||
struct can_mailbox *mb = NULL;
|
struct can_stm32_mailbox *mb = NULL;
|
||||||
|
|
||||||
LOG_DBG("Sending %d bytes on %s. "
|
LOG_DBG("Sending %d bytes on %s. "
|
||||||
"Id: 0x%x, "
|
"Id: 0x%x, "
|
||||||
|
@ -786,28 +785,28 @@ static int can_stm32_shift_arr(void **arr, int start, int count)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum can_filter_type can_stm32_get_filter_type(int bank_nr, uint32_t mode_reg,
|
static enum can_stm32_filter_type can_stm32_get_filter_type(int bank_num, uint32_t mode_reg,
|
||||||
uint32_t scale_reg)
|
uint32_t scale_reg)
|
||||||
{
|
{
|
||||||
uint32_t mode_masked = (mode_reg >> bank_nr) & 0x01;
|
uint32_t mode_masked = (mode_reg >> bank_num) & 0x01;
|
||||||
uint32_t scale_masked = (scale_reg >> bank_nr) & 0x01;
|
uint32_t scale_masked = (scale_reg >> bank_num) & 0x01;
|
||||||
enum can_filter_type type = (scale_masked << 1) | mode_masked;
|
enum can_stm32_filter_type type = (scale_masked << 1) | mode_masked;
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int can_calc_filter_index(int filter_id, int bank_offset, uint32_t mode_reg,
|
static int can_stm32_calc_filter_index(int filter_id, int bank_offset, uint32_t mode_reg,
|
||||||
uint32_t scale_reg)
|
uint32_t scale_reg)
|
||||||
{
|
{
|
||||||
int filter_bank = bank_offset + filter_id / 4;
|
int filter_bank = bank_offset + filter_id / 4;
|
||||||
int cnt = 0;
|
int cnt = 0;
|
||||||
uint32_t mode_masked, scale_masked;
|
uint32_t mode_masked, scale_masked;
|
||||||
enum can_filter_type filter_type;
|
enum can_stm32_filter_type filter_type;
|
||||||
|
|
||||||
/* count filters in the banks before this bank */
|
/* count filters in the banks before this bank */
|
||||||
for (int i = bank_offset; i < filter_bank; i++) {
|
for (int i = bank_offset; i < filter_bank; i++) {
|
||||||
filter_type = can_stm32_get_filter_type(i, mode_reg, scale_reg);
|
filter_type = can_stm32_get_filter_type(i, mode_reg, scale_reg);
|
||||||
cnt += filter_in_bank[filter_type];
|
cnt += max_filters_per_bank[filter_type];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* plus the filters in the same bank */
|
/* plus the filters in the same bank */
|
||||||
|
@ -820,11 +819,11 @@ static int can_calc_filter_index(int filter_id, int bank_offset, uint32_t mode_r
|
||||||
|
|
||||||
static void can_stm32_set_filter_bank(int filter_id,
|
static void can_stm32_set_filter_bank(int filter_id,
|
||||||
CAN_FilterRegister_TypeDef *filter_reg,
|
CAN_FilterRegister_TypeDef *filter_reg,
|
||||||
enum can_filter_type filter_type,
|
enum can_stm32_filter_type filter_type,
|
||||||
uint32_t id, uint32_t mask)
|
uint32_t id, uint32_t mask)
|
||||||
{
|
{
|
||||||
switch (filter_type) {
|
switch (filter_type) {
|
||||||
case CAN_FILTER_STANDARD:
|
case CAN_STM32_FILTER_STANDARD:
|
||||||
switch (filter_id & 0x03) {
|
switch (filter_id & 0x03) {
|
||||||
case 0:
|
case 0:
|
||||||
filter_reg->FR1 = (filter_reg->FR1 & 0xFFFF0000) | id;
|
filter_reg->FR1 = (filter_reg->FR1 & 0xFFFF0000) | id;
|
||||||
|
@ -843,7 +842,7 @@ static void can_stm32_set_filter_bank(int filter_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case CAN_FILTER_STANDARD_MASKED:
|
case CAN_STM32_FILTER_STANDARD_MASKED:
|
||||||
switch (filter_id & 0x02) {
|
switch (filter_id & 0x02) {
|
||||||
case 0:
|
case 0:
|
||||||
filter_reg->FR1 = id | (mask << 16);
|
filter_reg->FR1 = id | (mask << 16);
|
||||||
|
@ -854,7 +853,7 @@ static void can_stm32_set_filter_bank(int filter_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case CAN_FILTER_EXTENDED:
|
case CAN_STM32_FILTER_EXTENDED:
|
||||||
switch (filter_id & 0x02) {
|
switch (filter_id & 0x02) {
|
||||||
case 0:
|
case 0:
|
||||||
filter_reg->FR1 = id;
|
filter_reg->FR1 = id;
|
||||||
|
@ -865,54 +864,53 @@ static void can_stm32_set_filter_bank(int filter_id,
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case CAN_FILTER_EXTENDED_MASKED:
|
case CAN_STM32_FILTER_EXTENDED_MASKED:
|
||||||
filter_reg->FR1 = id;
|
filter_reg->FR1 = id;
|
||||||
filter_reg->FR2 = mask;
|
filter_reg->FR2 = mask;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void can_stm32_set_mode_scale(enum can_filter_type filter_type,
|
static inline void can_stm32_set_filter_type(enum can_stm32_filter_type filter_type,
|
||||||
uint32_t *mode_reg, uint32_t *scale_reg,
|
uint32_t *mode_reg, uint32_t *scale_reg,
|
||||||
int bank_nr)
|
int bank_num)
|
||||||
{
|
{
|
||||||
uint32_t mode_reg_bit = (filter_type & 0x01) << bank_nr;
|
uint32_t mode_reg_bit = (filter_type & 0x01) << bank_num;
|
||||||
uint32_t scale_reg_bit = (filter_type >> 1) << bank_nr;
|
uint32_t scale_reg_bit = (filter_type >> 1) << bank_num;
|
||||||
|
|
||||||
*mode_reg &= ~(1 << bank_nr);
|
*mode_reg &= ~(1 << bank_num);
|
||||||
*mode_reg |= mode_reg_bit;
|
*mode_reg |= mode_reg_bit;
|
||||||
|
|
||||||
*scale_reg &= ~(1 << bank_nr);
|
*scale_reg &= ~(1 << bank_num);
|
||||||
*scale_reg |= scale_reg_bit;
|
*scale_reg |= scale_reg_bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t can_generate_std_mask(const struct zcan_filter *filter)
|
static inline uint32_t can_stm32_filter_to_std_mask(const struct zcan_filter *filter)
|
||||||
{
|
{
|
||||||
return (filter->id_mask << CAN_FIRX_STD_ID_POS) |
|
return (filter->id_mask << CAN_STM32_FIRX_STD_ID_POS) |
|
||||||
(filter->rtr_mask << CAN_FIRX_STD_RTR_POS) |
|
(filter->rtr_mask << CAN_STM32_FIRX_STD_RTR_POS) |
|
||||||
(1U << CAN_FIRX_STD_IDE_POS);
|
(1U << CAN_STM32_FIRX_STD_IDE_POS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t can_generate_ext_mask(const struct zcan_filter *filter)
|
static inline uint32_t can_stm32_filter_to_ext_mask(const struct zcan_filter *filter)
|
||||||
{
|
{
|
||||||
return (filter->id_mask << CAN_FIRX_EXT_EXT_ID_POS) |
|
return (filter->id_mask << CAN_STM32_FIRX_EXT_EXT_ID_POS) |
|
||||||
(filter->rtr_mask << CAN_FIRX_EXT_RTR_POS) |
|
(filter->rtr_mask << CAN_STM32_FIRX_EXT_RTR_POS) |
|
||||||
(1U << CAN_FIRX_EXT_IDE_POS);
|
(1U << CAN_STM32_FIRX_EXT_IDE_POS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t can_generate_std_id(const struct zcan_filter *filter)
|
static inline uint32_t can_stm32_filter_to_std_id(const struct zcan_filter *filter)
|
||||||
{
|
{
|
||||||
|
return (filter->id << CAN_STM32_FIRX_STD_ID_POS) |
|
||||||
return (filter->id << CAN_FIRX_STD_ID_POS) |
|
(filter->rtr << CAN_STM32_FIRX_STD_RTR_POS);
|
||||||
(filter->rtr << CAN_FIRX_STD_RTR_POS);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t can_generate_ext_id(const struct zcan_filter *filter)
|
static inline uint32_t can_stm32_filter_to_ext_id(const struct zcan_filter *filter)
|
||||||
{
|
{
|
||||||
return (filter->id << CAN_FIRX_EXT_EXT_ID_POS) |
|
return (filter->id << CAN_STM32_FIRX_EXT_EXT_ID_POS) |
|
||||||
(filter->rtr << CAN_FIRX_EXT_RTR_POS) |
|
(filter->rtr << CAN_STM32_FIRX_EXT_RTR_POS) |
|
||||||
(1U << CAN_FIRX_EXT_IDE_POS);
|
(1U << CAN_STM32_FIRX_EXT_IDE_POS);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int can_stm32_set_filter(const struct device *dev, const struct zcan_filter *filter,
|
static inline int can_stm32_set_filter(const struct device *dev, const struct zcan_filter *filter,
|
||||||
|
@ -925,46 +923,46 @@ static inline int can_stm32_set_filter(const struct device *dev, const struct zc
|
||||||
uint32_t id = 0U;
|
uint32_t id = 0U;
|
||||||
int filter_id = 0;
|
int filter_id = 0;
|
||||||
int filter_index_new = -ENOSPC;
|
int filter_index_new = -ENOSPC;
|
||||||
int bank_nr;
|
int bank_num;
|
||||||
int bank_offset = 0;
|
int bank_offset = 0;
|
||||||
uint32_t bank_bit;
|
uint32_t bank_bit;
|
||||||
int register_demand;
|
int register_demand;
|
||||||
enum can_filter_type filter_type;
|
enum can_stm32_filter_type filter_type;
|
||||||
enum can_filter_type bank_mode;
|
enum can_stm32_filter_type bank_type;
|
||||||
|
|
||||||
if (cfg->can != cfg->master_can) {
|
if (cfg->can != cfg->master_can) {
|
||||||
/* CAN slave instance: start with offset */
|
/* CAN slave instance: start with offset */
|
||||||
bank_offset = CAN_NUMBER_OF_FILTER_BANKS;
|
bank_offset = CAN_STM32_NUM_FILTER_BANKS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filter->id_type == CAN_STANDARD_IDENTIFIER) {
|
if (filter->id_type == CAN_STANDARD_IDENTIFIER) {
|
||||||
id = can_generate_std_id(filter);
|
id = can_stm32_filter_to_std_id(filter);
|
||||||
filter_type = CAN_FILTER_STANDARD;
|
filter_type = CAN_STM32_FILTER_STANDARD;
|
||||||
|
|
||||||
if (filter->id_mask != CAN_STD_ID_MASK) {
|
if (filter->id_mask != CAN_STD_ID_MASK) {
|
||||||
mask = can_generate_std_mask(filter);
|
mask = can_stm32_filter_to_std_mask(filter);
|
||||||
filter_type = CAN_FILTER_STANDARD_MASKED;
|
filter_type = CAN_STM32_FILTER_STANDARD_MASKED;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
id = can_generate_ext_id(filter);
|
id = can_stm32_filter_to_ext_id(filter);
|
||||||
filter_type = CAN_FILTER_EXTENDED;
|
filter_type = CAN_STM32_FILTER_EXTENDED;
|
||||||
|
|
||||||
if (filter->id_mask != CAN_EXT_ID_MASK) {
|
if (filter->id_mask != CAN_EXT_ID_MASK) {
|
||||||
mask = can_generate_ext_mask(filter);
|
mask = can_stm32_filter_to_ext_mask(filter);
|
||||||
filter_type = CAN_FILTER_EXTENDED_MASKED;
|
filter_type = CAN_STM32_FILTER_EXTENDED_MASKED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
register_demand = reg_demand[filter_type];
|
register_demand = filter_reg_demand[filter_type];
|
||||||
|
|
||||||
LOG_DBG("Setting filter ID: 0x%x, mask: 0x%x", filter->id,
|
LOG_DBG("Setting filter ID: 0x%x, mask: 0x%x", filter->id,
|
||||||
filter->id_mask);
|
filter->id_mask);
|
||||||
LOG_DBG("Filter type: %s ID %s mask (%d)",
|
LOG_DBG("Filter type: %s ID %s mask (%d)",
|
||||||
(filter_type == CAN_FILTER_STANDARD ||
|
(filter_type == CAN_STM32_FILTER_STANDARD ||
|
||||||
filter_type == CAN_FILTER_STANDARD_MASKED) ?
|
filter_type == CAN_STM32_FILTER_STANDARD_MASKED) ?
|
||||||
"standard" : "extended",
|
"standard" : "extended",
|
||||||
(filter_type == CAN_FILTER_STANDARD_MASKED ||
|
(filter_type == CAN_STM32_FILTER_STANDARD_MASKED ||
|
||||||
filter_type == CAN_FILTER_EXTENDED_MASKED) ?
|
filter_type == CAN_STM32_FILTER_EXTENDED_MASKED) ?
|
||||||
"with" : "without",
|
"with" : "without",
|
||||||
filter_type);
|
filter_type);
|
||||||
|
|
||||||
|
@ -973,15 +971,15 @@ static inline int can_stm32_set_filter(const struct device *dev, const struct zc
|
||||||
uint64_t usage_demand_mask = (1ULL << register_demand) - 1;
|
uint64_t usage_demand_mask = (1ULL << register_demand) - 1;
|
||||||
bool bank_is_empty;
|
bool bank_is_empty;
|
||||||
|
|
||||||
bank_nr = bank_offset + filter_id / 4;
|
bank_num = bank_offset + filter_id / 4;
|
||||||
bank_bit = (1U << bank_nr);
|
bank_bit = (1U << bank_num);
|
||||||
bank_mode = can_stm32_get_filter_type(bank_nr, can->FM1R,
|
bank_type = can_stm32_get_filter_type(bank_num, can->FM1R,
|
||||||
can->FS1R);
|
can->FS1R);
|
||||||
|
|
||||||
bank_is_empty = CAN_BANK_IS_EMPTY(device_data->filter_usage,
|
bank_is_empty = CAN_STM32_BANK_IS_EMPTY(device_data->filter_usage,
|
||||||
bank_nr, bank_offset);
|
bank_num, bank_offset);
|
||||||
|
|
||||||
if (!bank_is_empty && bank_mode != filter_type) {
|
if (!bank_is_empty && bank_type != filter_type) {
|
||||||
filter_id = (filter_id / 4 + 1) * 4;
|
filter_id = (filter_id / 4 + 1) * 4;
|
||||||
} else if (usage_shifted & usage_demand_mask) {
|
} else if (usage_shifted & usage_demand_mask) {
|
||||||
device_data->filter_usage &=
|
device_data->filter_usage &=
|
||||||
|
@ -995,37 +993,34 @@ static inline int can_stm32_set_filter(const struct device *dev, const struct zc
|
||||||
LOG_INF("No free filter bank found");
|
LOG_INF("No free filter bank found");
|
||||||
return -ENOSPC;
|
return -ENOSPC;
|
||||||
}
|
}
|
||||||
} while (filter_id < CAN_MAX_NUMBER_OF_FILTERS);
|
} while (filter_id < CAN_STM32_MAX_NUM_FILTERS);
|
||||||
|
|
||||||
/* set the filter init mode */
|
/* set the filter init mode */
|
||||||
can->FMR |= CAN_FMR_FINIT;
|
can->FMR |= CAN_FMR_FINIT;
|
||||||
can->FA1R &= ~bank_bit;
|
can->FA1R &= ~bank_bit;
|
||||||
|
|
||||||
/* TODO fifo balancing */
|
/* TODO fifo balancing */
|
||||||
if (filter_type != bank_mode) {
|
if (filter_type != bank_type) {
|
||||||
int shift_width, start_index;
|
int shift_width, start_index;
|
||||||
int res;
|
int res;
|
||||||
uint32_t mode_reg = can->FM1R;
|
uint32_t mode_reg = can->FM1R;
|
||||||
uint32_t scale_reg = can->FS1R;
|
uint32_t scale_reg = can->FS1R;
|
||||||
|
|
||||||
can_stm32_set_mode_scale(filter_type, &mode_reg, &scale_reg,
|
can_stm32_set_filter_type(filter_type, &mode_reg, &scale_reg, bank_num);
|
||||||
bank_nr);
|
|
||||||
|
|
||||||
shift_width = filter_in_bank[filter_type] - filter_in_bank[bank_mode];
|
shift_width = max_filters_per_bank[filter_type] - max_filters_per_bank[bank_type];
|
||||||
|
|
||||||
filter_index_new = can_calc_filter_index(filter_id, bank_offset,
|
filter_index_new = can_stm32_calc_filter_index(filter_id, bank_offset,
|
||||||
mode_reg, scale_reg);
|
mode_reg, scale_reg);
|
||||||
|
|
||||||
start_index = filter_index_new + filter_in_bank[bank_mode];
|
start_index = filter_index_new + max_filters_per_bank[bank_type];
|
||||||
|
|
||||||
if (shift_width && start_index <= CAN_MAX_NUMBER_OF_FILTERS) {
|
if (shift_width && start_index <= CAN_STM32_MAX_NUM_FILTERS) {
|
||||||
res = can_stm32_shift_arr((void **)device_data->rx_cb,
|
res = can_stm32_shift_arr((void **)device_data->rx_cb,
|
||||||
start_index,
|
start_index, shift_width);
|
||||||
shift_width);
|
|
||||||
|
|
||||||
res |= can_stm32_shift_arr(device_data->cb_arg,
|
res |= can_stm32_shift_arr(device_data->cb_arg,
|
||||||
start_index,
|
start_index, shift_width);
|
||||||
shift_width);
|
|
||||||
|
|
||||||
if (filter_index_new >= CONFIG_CAN_MAX_FILTER || res) {
|
if (filter_index_new >= CONFIG_CAN_MAX_FILTER || res) {
|
||||||
LOG_INF("No space for a new filter!");
|
LOG_INF("No space for a new filter!");
|
||||||
|
@ -1037,20 +1032,20 @@ static inline int can_stm32_set_filter(const struct device *dev, const struct zc
|
||||||
can->FM1R = mode_reg;
|
can->FM1R = mode_reg;
|
||||||
can->FS1R = scale_reg;
|
can->FS1R = scale_reg;
|
||||||
} else {
|
} else {
|
||||||
filter_index_new = can_calc_filter_index(filter_id, bank_offset,
|
filter_index_new = can_stm32_calc_filter_index(filter_id, bank_offset,
|
||||||
can->FM1R, can->FS1R);
|
can->FM1R, can->FS1R);
|
||||||
if (filter_index_new >= CAN_MAX_NUMBER_OF_FILTERS) {
|
if (filter_index_new >= CAN_STM32_MAX_NUM_FILTERS) {
|
||||||
filter_id = -ENOSPC;
|
filter_id = -ENOSPC;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
can_stm32_set_filter_bank(filter_id, &can->sFilterRegister[bank_nr],
|
can_stm32_set_filter_bank(filter_id, &can->sFilterRegister[bank_num],
|
||||||
filter_type, id, mask);
|
filter_type, id, mask);
|
||||||
done:
|
done:
|
||||||
can->FA1R |= bank_bit;
|
can->FA1R |= bank_bit;
|
||||||
can->FMR &= ~(CAN_FMR_FINIT);
|
can->FMR &= ~(CAN_FMR_FINIT);
|
||||||
LOG_DBG("Filter set: id %d, index %d, bank %d", filter_id, filter_index_new, bank_nr);
|
LOG_DBG("Filter set: id %d, index %d, bank %d", filter_id, filter_index_new, bank_num);
|
||||||
*filter_index = filter_index_new;
|
*filter_index = filter_index_new;
|
||||||
return filter_id;
|
return filter_id;
|
||||||
}
|
}
|
||||||
|
@ -1083,47 +1078,47 @@ static void can_stm32_remove_rx_filter(const struct device *dev, int filter_id)
|
||||||
struct can_stm32_data *data = dev->data;
|
struct can_stm32_data *data = dev->data;
|
||||||
CAN_TypeDef *can = cfg->master_can;
|
CAN_TypeDef *can = cfg->master_can;
|
||||||
int bank_offset = 0;
|
int bank_offset = 0;
|
||||||
int bank_nr;
|
int bank_num;
|
||||||
int filter_index;
|
int filter_index;
|
||||||
uint32_t bank_bit;
|
uint32_t bank_bit;
|
||||||
uint32_t mode_reg;
|
uint32_t mode_reg;
|
||||||
uint32_t scale_reg;
|
uint32_t scale_reg;
|
||||||
enum can_filter_type type;
|
enum can_stm32_filter_type type;
|
||||||
uint32_t reset_mask;
|
uint32_t reset_mask;
|
||||||
|
|
||||||
__ASSERT_NO_MSG(filter_id >= 0 && filter_id < CAN_MAX_NUMBER_OF_FILTERS);
|
__ASSERT_NO_MSG(filter_id >= 0 && filter_id < CAN_STM32_MAX_NUM_FILTERS);
|
||||||
|
|
||||||
k_mutex_lock(&filter_mutex, K_FOREVER);
|
k_mutex_lock(&filter_mutex, K_FOREVER);
|
||||||
k_mutex_lock(&data->inst_mutex, K_FOREVER);
|
k_mutex_lock(&data->inst_mutex, K_FOREVER);
|
||||||
|
|
||||||
if (cfg->can != cfg->master_can) {
|
if (cfg->can != cfg->master_can) {
|
||||||
bank_offset = CAN_NUMBER_OF_FILTER_BANKS;
|
bank_offset = CAN_STM32_NUM_FILTER_BANKS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bank_nr = bank_offset + filter_id / 4;
|
bank_num = bank_offset + filter_id / 4;
|
||||||
bank_bit = (1U << bank_nr);
|
bank_bit = (1U << bank_num);
|
||||||
mode_reg = can->FM1R;
|
mode_reg = can->FM1R;
|
||||||
scale_reg = can->FS1R;
|
scale_reg = can->FS1R;
|
||||||
|
|
||||||
filter_index = can_calc_filter_index(filter_id, bank_offset, mode_reg, scale_reg);
|
filter_index = can_stm32_calc_filter_index(filter_id, bank_offset, mode_reg, scale_reg);
|
||||||
type = can_stm32_get_filter_type(bank_nr, mode_reg, scale_reg);
|
type = can_stm32_get_filter_type(bank_num, mode_reg, scale_reg);
|
||||||
|
|
||||||
LOG_DBG("Detach filter number %d (index %d), type %d", filter_id,
|
LOG_DBG("Detach filter number %d (index %d), type %d", filter_id,
|
||||||
filter_index,
|
filter_index,
|
||||||
type);
|
type);
|
||||||
|
|
||||||
reset_mask = ((1 << (reg_demand[type])) - 1) << filter_id;
|
reset_mask = ((1 << (filter_reg_demand[type])) - 1) << filter_id;
|
||||||
data->filter_usage |= reset_mask;
|
data->filter_usage |= reset_mask;
|
||||||
can->FMR |= CAN_FMR_FINIT;
|
can->FMR |= CAN_FMR_FINIT;
|
||||||
can->FA1R &= ~bank_bit;
|
can->FA1R &= ~bank_bit;
|
||||||
|
|
||||||
can_stm32_set_filter_bank(filter_id, &can->sFilterRegister[bank_nr],
|
can_stm32_set_filter_bank(filter_id, &can->sFilterRegister[bank_num],
|
||||||
type, 0, 0xFFFFFFFF);
|
type, 0, 0xFFFFFFFF);
|
||||||
|
|
||||||
if (!CAN_BANK_IS_EMPTY(data->filter_usage, bank_nr, bank_offset)) {
|
if (!CAN_STM32_BANK_IS_EMPTY(data->filter_usage, bank_num, bank_offset)) {
|
||||||
can->FA1R |= bank_bit;
|
can->FA1R |= bank_bit;
|
||||||
} else {
|
} else {
|
||||||
LOG_DBG("Bank number %d is empty -> deactivate", bank_nr);
|
LOG_DBG("Bank number %d is empty -> deactivate", bank_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
can->FMR &= ~(CAN_FMR_FINIT);
|
can->FMR &= ~(CAN_FMR_FINIT);
|
||||||
|
|
|
@ -2,62 +2,49 @@
|
||||||
* Copyright (c) 2018 Alexander Wachter
|
* Copyright (c) 2018 Alexander Wachter
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ZEPHYR_DRIVERS_CAN_STM32_CAN_H_
|
#ifndef ZEPHYR_DRIVERS_CAN_STM32_H_
|
||||||
#define ZEPHYR_DRIVERS_CAN_STM32_CAN_H_
|
#define ZEPHYR_DRIVERS_CAN_STM32_H_
|
||||||
|
|
||||||
#include <zephyr/drivers/can.h>
|
#include <zephyr/drivers/can.h>
|
||||||
|
|
||||||
#define BIT_SEG_LENGTH(cfg) ((cfg)->prop_ts1 + (cfg)->ts2 + 1)
|
#define CAN_STM32_NUM_FILTER_BANKS (14)
|
||||||
|
#define CAN_STM32_MAX_NUM_FILTERS (CAN_STM32_NUM_FILTER_BANKS * 4)
|
||||||
|
|
||||||
#define CAN_NUMBER_OF_FILTER_BANKS (14)
|
#define CAN_STM32_FIRX_STD_IDE_POS (3U)
|
||||||
#define CAN_MAX_NUMBER_OF_FILTERS (CAN_NUMBER_OF_FILTER_BANKS * 4)
|
#define CAN_STM32_FIRX_STD_RTR_POS (4U)
|
||||||
|
#define CAN_STM32_FIRX_STD_ID_POS (5U)
|
||||||
|
|
||||||
#define CAN_FIRX_STD_IDE_POS (3U)
|
#define CAN_STM32_FIRX_EXT_IDE_POS (2U)
|
||||||
#define CAN_FIRX_STD_RTR_POS (4U)
|
#define CAN_STM32_FIRX_EXT_RTR_POS (1U)
|
||||||
#define CAN_FIRX_STD_ID_POS (5U)
|
#define CAN_STM32_FIRX_EXT_STD_ID_POS (21U)
|
||||||
|
#define CAN_STM32_FIRX_EXT_EXT_ID_POS (3U)
|
||||||
|
|
||||||
#define CAN_FIRX_EXT_IDE_POS (2U)
|
#define CAN_STM32_BANK_IS_EMPTY(usage, bank_nr, bank_offset) \
|
||||||
#define CAN_FIRX_EXT_RTR_POS (1U)
|
|
||||||
#define CAN_FIRX_EXT_STD_ID_POS (21U)
|
|
||||||
#define CAN_FIRX_EXT_EXT_ID_POS (3U)
|
|
||||||
|
|
||||||
#define CAN_BANK_IS_EMPTY(usage, bank_nr, bank_offset) \
|
|
||||||
(((usage >> ((bank_nr - bank_offset) * 4)) & 0x0F) == 0x0F)
|
(((usage >> ((bank_nr - bank_offset) * 4)) & 0x0F) == 0x0F)
|
||||||
#define CAN_BANK_IN_LIST_MODE(can, bank) ((can)->FM1R & (1U << (bank)))
|
|
||||||
#define CAN_BANK_IN_32BIT_MODE(can, bank) ((can)->FS1R & (1U << (bank)))
|
struct can_stm32_mailbox {
|
||||||
#define CAN_IN_16BIT_LIST_MODE(can, bank) (CAN_BANK_IN_LIST_MODE(can, bank) && \
|
|
||||||
!CAN_BANK_IN_32BIT_MODE(can, bank))
|
|
||||||
#define CAN_IN_16BIT_MASK_MODE(can, bank) (!CAN_BANK_IN_LIST_MODE(can, bank) && \
|
|
||||||
!CAN_BANK_IN_32BIT_MODE(can, bank))
|
|
||||||
#define CAN_IN_32BIT_LIST_MODE(can, bank) (CAN_BANK_IN_LIST_MODE(can, bank) && \
|
|
||||||
CAN_BANK_IN_32BIT_MODE(can, bank))
|
|
||||||
#define CAN_IN_32BIT_MASK_MODE(can, bank) (!CAN_BANK_IN_LIST_MODE(can, bank) && \
|
|
||||||
CAN_BANK_IN_32BIT_MODE(can, bank))
|
|
||||||
struct can_mailbox {
|
|
||||||
can_tx_callback_t tx_callback;
|
can_tx_callback_t tx_callback;
|
||||||
void *callback_arg;
|
void *callback_arg;
|
||||||
struct k_sem tx_int_sem;
|
struct k_sem tx_int_sem;
|
||||||
int error;
|
int error;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* number = FSCx | FMBx */
|
/* number = FSCx | FMBx */
|
||||||
enum can_filter_type {
|
enum can_stm32_filter_type {
|
||||||
CAN_FILTER_STANDARD_MASKED = 0,
|
CAN_STM32_FILTER_STANDARD_MASKED = 0,
|
||||||
CAN_FILTER_STANDARD = 1,
|
CAN_STM32_FILTER_STANDARD = 1,
|
||||||
CAN_FILTER_EXTENDED_MASKED = 2,
|
CAN_STM32_FILTER_EXTENDED_MASKED = 2,
|
||||||
CAN_FILTER_EXTENDED = 3
|
CAN_STM32_FILTER_EXTENDED = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
struct can_stm32_data {
|
struct can_stm32_data {
|
||||||
struct k_mutex inst_mutex;
|
struct k_mutex inst_mutex;
|
||||||
struct k_sem tx_int_sem;
|
struct k_sem tx_int_sem;
|
||||||
struct can_mailbox mb0;
|
struct can_stm32_mailbox mb0;
|
||||||
struct can_mailbox mb1;
|
struct can_stm32_mailbox mb1;
|
||||||
struct can_mailbox mb2;
|
struct can_stm32_mailbox mb2;
|
||||||
uint64_t filter_usage;
|
uint64_t filter_usage;
|
||||||
can_rx_callback_t rx_cb[CONFIG_CAN_MAX_FILTER];
|
can_rx_callback_t rx_cb[CONFIG_CAN_MAX_FILTER];
|
||||||
void *cb_arg[CONFIG_CAN_MAX_FILTER];
|
void *cb_arg[CONFIG_CAN_MAX_FILTER];
|
||||||
|
@ -81,4 +68,4 @@ struct can_stm32_config {
|
||||||
uint32_t max_bitrate;
|
uint32_t max_bitrate;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /*ZEPHYR_DRIVERS_CAN_STM32_CAN_H_*/
|
#endif /* ZEPHYR_DRIVERS_CAN_STM32_H_ */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue