drivers: can: Move bit timing and clock to device tree
This commit moves the bit timing (PROP, BS1, BS2 segments and SWJ) from Kconfig to the device-tree and fixes issue #7933 Signed-off-by: Alexander Wachter <alexander.wachter@student.tugraz.at>
This commit is contained in:
parent
997a49ade9
commit
b97dd472fb
8 changed files with 56 additions and 41 deletions
|
@ -41,6 +41,11 @@
|
||||||
#define CONFIG_CAN_1_NAME ST_STM32_CAN_40006400_LABEL
|
#define CONFIG_CAN_1_NAME ST_STM32_CAN_40006400_LABEL
|
||||||
#define CONFIG_CAN_1_IRQ ST_STM32_CAN_40006400_IRQ_0
|
#define CONFIG_CAN_1_IRQ ST_STM32_CAN_40006400_IRQ_0
|
||||||
#define CONFIG_CAN_1_IRQ_PRIORITY ST_STM32_CAN_40006400_IRQ_0_PRIORITY
|
#define CONFIG_CAN_1_IRQ_PRIORITY ST_STM32_CAN_40006400_IRQ_0_PRIORITY
|
||||||
|
#define CONFIG_CAN_1_SJW ST_STM32_CAN_40006400_SJW
|
||||||
|
#define CONFIG_CAN_1_PROP_SEG_PHASE_SEG1 ST_STM32_CAN_40006400_PROP_SEG_PHASE_SEG1
|
||||||
|
#define CONFIG_CAN_1_PHASE_SEG2 ST_STM32_CAN_40006400_PHASE_SEG2
|
||||||
|
#define CONFIG_CAN_1_CLOCK_BUS ST_STM32_CAN_40006400_CLOCK_BUS
|
||||||
|
#define CONFIG_CAN_1_CLOCK_BITS ST_STM32_CAN_40006400_CLOCK_BITS
|
||||||
|
|
||||||
#define FLASH_DEV_BASE_ADDRESS ST_STM32F0_FLASH_CONTROLLER_40022000_BASE_ADDRESS
|
#define FLASH_DEV_BASE_ADDRESS ST_STM32F0_FLASH_CONTROLLER_40022000_BASE_ADDRESS
|
||||||
#define FLASH_DEV_NAME ST_STM32F0_FLASH_CONTROLLER_40022000_LABEL
|
#define FLASH_DEV_NAME ST_STM32F0_FLASH_CONTROLLER_40022000_LABEL
|
||||||
|
|
|
@ -40,27 +40,6 @@ config CAN_INIT_PRIORITY
|
||||||
Note that the priority needs to be lower than the net stack
|
Note that the priority needs to be lower than the net stack
|
||||||
so that it can start before the networking sub-system.
|
so that it can start before the networking sub-system.
|
||||||
|
|
||||||
config CAN_PHASE_SEG1_PROP_SEG
|
|
||||||
int "Phase_Seg1_Prop_Seg"
|
|
||||||
default 5
|
|
||||||
range 1 16
|
|
||||||
help
|
|
||||||
Time quanta of phase buffer 1 segment + propagation segment (ISO 11898-1)
|
|
||||||
|
|
||||||
config CAN_PHASE_SEG2
|
|
||||||
int "Phase_Seg2"
|
|
||||||
default 6
|
|
||||||
range 1 8
|
|
||||||
help
|
|
||||||
Time quanta of phase buffer 2 segment (ISO 11898-1)
|
|
||||||
|
|
||||||
config CAN_SJW
|
|
||||||
int "SJW"
|
|
||||||
default 1
|
|
||||||
range 1 4
|
|
||||||
help
|
|
||||||
Resynchronization jump width (ISO 11898-1)
|
|
||||||
|
|
||||||
config CAN_1
|
config CAN_1
|
||||||
bool "Enable CAN 1"
|
bool "Enable CAN 1"
|
||||||
default y
|
default y
|
||||||
|
|
|
@ -94,17 +94,17 @@ static void can_stm32_isr(void *arg)
|
||||||
can_stm32_signal_tx_complete(&data->mb2);
|
can_stm32_signal_tx_complete(&data->mb2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (can->TSR & CAN_TSR_TME_Msk) {
|
if (can->TSR & CAN_TSR_TME) {
|
||||||
k_sem_give(&data->tx_int_sem);
|
k_sem_give(&data->tx_int_sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (can->RF0R & CAN_RF0R_FMP0_Msk) {
|
while (can->RF0R & CAN_RF0R_FMP0) {
|
||||||
CAN_FIFOMailBox_TypeDef *mbox;
|
CAN_FIFOMailBox_TypeDef *mbox;
|
||||||
int filter_match_index;
|
int filter_match_index;
|
||||||
struct can_msg msg;
|
struct can_msg msg;
|
||||||
|
|
||||||
mbox = &can->sFIFOMailBox[0];
|
mbox = &can->sFIFOMailBox[0];
|
||||||
filter_match_index = ((mbox->RDTR & CAN_RDT0R_FMI_Msk)
|
filter_match_index = ((mbox->RDTR & CAN_RDT0R_FMI)
|
||||||
>> CAN_RDT0R_FMI_Pos);
|
>> CAN_RDT0R_FMI_Pos);
|
||||||
|
|
||||||
if (filter_match_index >= CONFIG_CAN_MAX_FILTER) {
|
if (filter_match_index >= CONFIG_CAN_MAX_FILTER) {
|
||||||
|
@ -162,16 +162,31 @@ int can_stm32_runtime_configure(struct device *dev, enum can_mode mode,
|
||||||
bitrate = cfg->bus_speed;
|
bitrate = cfg->bus_speed;
|
||||||
}
|
}
|
||||||
|
|
||||||
prescaler = clock_rate / (BIT_SEG_LENGTH * cfg->bus_speed);
|
prescaler = clock_rate / (BIT_SEG_LENGTH(cfg) * bitrate);
|
||||||
if (prescaler == 0 || prescaler > 1024) {
|
if (prescaler == 0 || prescaler > 1024) {
|
||||||
SYS_LOG_ERR("HAL_CAN_Init failed: prescaler > max (%d > 1024)",
|
SYS_LOG_ERR("HAL_CAN_Init failed: prescaler > max (%d > 1024)",
|
||||||
prescaler);
|
prescaler);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
bs1 = (CONFIG_CAN_PHASE_SEG1_PROP_SEG - 1) << CAN_BTR_TS1_Pos;
|
if (clock_rate % (BIT_SEG_LENGTH(cfg) * bitrate)) {
|
||||||
bs2 = (CONFIG_CAN_PHASE_SEG2 - 1) << CAN_BTR_TS2_Pos;
|
SYS_LOG_ERR("Prescaler is not a natural number! "
|
||||||
swj = (CONFIG_CAN_SJW - 1) << CAN_BTR_SJW_Pos;
|
"prescaler = clock_rate / ((PROP_SEG1 + SEG2 + 1)"
|
||||||
|
" * bus_speed); "
|
||||||
|
"prescaler = %d / ((%d + %d + 1) * %d)",
|
||||||
|
clock_rate,
|
||||||
|
cfg->prop_bs1,
|
||||||
|
cfg->bs2,
|
||||||
|
bitrate);
|
||||||
|
}
|
||||||
|
|
||||||
|
__ASSERT(cfg->swj <= 0x03, "SWJ maximum is 3");
|
||||||
|
__ASSERT(cfg->prop_bs1 <= 0x0F, "PROP_BS1 maximum is 15");
|
||||||
|
__ASSERT(cfg->bs2 <= 0x07, "BS2 maximum is 7");
|
||||||
|
|
||||||
|
bs1 = ((cfg->prop_bs1 & 0x0F) - 1) << CAN_BTR_TS1_Pos;
|
||||||
|
bs2 = ((cfg->bs2 & 0x07) - 1) << CAN_BTR_TS2_Pos;
|
||||||
|
swj = ((cfg->swj & 0x07) - 1) << CAN_BTR_SJW_Pos;
|
||||||
|
|
||||||
hal_mode = mode == CAN_NORMAL_MODE ? CAN_MODE_NORMAL :
|
hal_mode = mode == CAN_NORMAL_MODE ? CAN_MODE_NORMAL :
|
||||||
mode == CAN_LOOPBACK_MODE ? CAN_MODE_LOOPBACK :
|
mode == CAN_LOOPBACK_MODE ? CAN_MODE_LOOPBACK :
|
||||||
|
@ -272,7 +287,7 @@ int can_stm32_send(struct device *dev, struct can_msg *msg, s32_t timeout,
|
||||||
}
|
}
|
||||||
|
|
||||||
k_mutex_lock(tx_mutex, K_FOREVER);
|
k_mutex_lock(tx_mutex, K_FOREVER);
|
||||||
while (!(transmit_status_register & CAN_TSR_TME_Msk)) {
|
while (!(transmit_status_register & CAN_TSR_TME)) {
|
||||||
k_mutex_unlock(tx_mutex);
|
k_mutex_unlock(tx_mutex);
|
||||||
SYS_LOG_DBG("Transmit buffer full. Wait with timeout (%dms)",
|
SYS_LOG_DBG("Transmit buffer full. Wait with timeout (%dms)",
|
||||||
timeout);
|
timeout);
|
||||||
|
@ -314,7 +329,7 @@ int can_stm32_send(struct device *dev, struct can_msg *msg, s32_t timeout,
|
||||||
mailbox->TIR |= CAN_TI1R_RTR;
|
mailbox->TIR |= CAN_TI1R_RTR;
|
||||||
}
|
}
|
||||||
|
|
||||||
mailbox->TDTR = (mailbox->TDTR & ~CAN_TDT1R_DLC_Msk) |
|
mailbox->TDTR = (mailbox->TDTR & ~CAN_TDT1R_DLC) |
|
||||||
((msg->dlc & 0xF) << CAN_TDT1R_DLC_Pos);
|
((msg->dlc & 0xF) << CAN_TDT1R_DLC_Pos);
|
||||||
|
|
||||||
mailbox->TDLR = msg->data_32[0];
|
mailbox->TDLR = msg->data_32[0];
|
||||||
|
@ -779,6 +794,9 @@ static void config_can_1_irq(CAN_TypeDef *can);
|
||||||
static const struct can_stm32_config can_stm32_cfg_1 = {
|
static const struct can_stm32_config can_stm32_cfg_1 = {
|
||||||
.can = (CAN_TypeDef *)CONFIG_CAN_1_BASE_ADDRESS,
|
.can = (CAN_TypeDef *)CONFIG_CAN_1_BASE_ADDRESS,
|
||||||
.bus_speed = CONFIG_CAN_1_BUS_SPEED,
|
.bus_speed = CONFIG_CAN_1_BUS_SPEED,
|
||||||
|
.swj = CONFIG_CAN_1_SJW,
|
||||||
|
.prop_bs1 = CONFIG_CAN_1_PROP_SEG_PHASE_SEG1,
|
||||||
|
.bs2 = CONFIG_CAN_1_PHASE_SEG2,
|
||||||
.pclken = {
|
.pclken = {
|
||||||
.enr = RCC_APB1ENR_CANEN,
|
.enr = RCC_APB1ENR_CANEN,
|
||||||
.bus = STM32_CLOCK_BUS_APB1,
|
.bus = STM32_CLOCK_BUS_APB1,
|
||||||
|
|
|
@ -14,8 +14,7 @@
|
||||||
#define DEV_CFG(dev) \
|
#define DEV_CFG(dev) \
|
||||||
((const struct can_stm32_config *const)(dev)->config->config_info)
|
((const struct can_stm32_config *const)(dev)->config->config_info)
|
||||||
|
|
||||||
#define BIT_SEG_LENGTH ((CONFIG_CAN_PHASE_SEG1_PROP_SEG) \
|
#define BIT_SEG_LENGTH(cfg) ((cfg)->prop_bs1 + (cfg)->bs2 + 1)
|
||||||
+ (CONFIG_CAN_PHASE_SEG2) + 1)
|
|
||||||
|
|
||||||
#define CAN_NUMBER_OF_FILTER_BANKS (14)
|
#define CAN_NUMBER_OF_FILTER_BANKS (14)
|
||||||
#define CAN_MAX_NUMBER_OF_FILTES (CAN_NUMBER_OF_FILTER_BANKS * 4)
|
#define CAN_MAX_NUMBER_OF_FILTES (CAN_NUMBER_OF_FILTER_BANKS * 4)
|
||||||
|
@ -68,6 +67,9 @@ struct can_stm32_data {
|
||||||
struct can_stm32_config {
|
struct can_stm32_config {
|
||||||
CAN_TypeDef *can; /*!< CAN Registers*/
|
CAN_TypeDef *can; /*!< CAN Registers*/
|
||||||
u32_t bus_speed;
|
u32_t bus_speed;
|
||||||
|
u8_t swj;
|
||||||
|
u8_t prop_bs1;
|
||||||
|
u8_t bs2;
|
||||||
struct stm32_pclken pclken;
|
struct stm32_pclken pclken;
|
||||||
void (*config_irq)(CAN_TypeDef *can);
|
void (*config_irq)(CAN_TypeDef *can);
|
||||||
};
|
};
|
||||||
|
|
|
@ -51,6 +51,10 @@
|
||||||
interrupts = <30 0>;
|
interrupts = <30 0>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
label = "CAN_1";
|
label = "CAN_1";
|
||||||
|
bus-speed = <250000>;
|
||||||
|
sjw = <1>;
|
||||||
|
prop_seg_phase_seg1 = <5>;
|
||||||
|
phase_seg2 = <6>;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,9 +29,4 @@ properties:
|
||||||
category: required
|
category: required
|
||||||
description: Human readable string describing the device (used by Zephyr for API name)
|
description: Human readable string describing the device (used by Zephyr for API name)
|
||||||
generation: define
|
generation: define
|
||||||
bus-speed:
|
|
||||||
type: int
|
|
||||||
category: required
|
|
||||||
description: bus spees in Baud/s
|
|
||||||
generation: define
|
|
||||||
...
|
...
|
||||||
|
|
|
@ -26,7 +26,22 @@ properties:
|
||||||
bus-speed:
|
bus-speed:
|
||||||
type: int
|
type: int
|
||||||
category: required
|
category: required
|
||||||
description: bus spees in Baud/s
|
description: bus speed in Baud/s
|
||||||
|
generation: define
|
||||||
|
sjw:
|
||||||
|
type: int
|
||||||
|
category: required
|
||||||
|
description: Resynchronization jump width (ISO 11898-1)
|
||||||
|
generation: define
|
||||||
|
prop_seg_phase_seg1:
|
||||||
|
type: int
|
||||||
|
category: required
|
||||||
|
description: Time quantums of phase buffer 1 segment + propagation segment (ISO 11898-1)
|
||||||
|
generation: define
|
||||||
|
phase_seg2:
|
||||||
|
type: int
|
||||||
|
category: required
|
||||||
|
description: Time quantums of phase buffer 2 segment (ISO 11898-1)
|
||||||
generation: define
|
generation: define
|
||||||
pinctrl-\d+:
|
pinctrl-\d+:
|
||||||
type: array
|
type: array
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
CONFIG_CAN=y
|
CONFIG_CAN=y
|
||||||
CONFIG_CAN_INIT_PRIORITY=80
|
CONFIG_CAN_INIT_PRIORITY=80
|
||||||
CONFIG_CAN_PHASE_SEG1_PROP_SEG=5
|
|
||||||
CONFIG_CAN_PHASE_SEG2=6
|
|
||||||
CONFIG_CAN_SJW=1
|
|
||||||
CONFIG_CAN_1=y
|
CONFIG_CAN_1=y
|
||||||
CONFIG_CAN_STM32=y
|
CONFIG_CAN_STM32=y
|
||||||
CONFIG_CAN_MAX_FILTER=5
|
CONFIG_CAN_MAX_FILTER=5
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue