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:
Alexander Wachter 2018-05-29 16:10:31 +02:00 committed by Maureen Helm
commit b97dd472fb
8 changed files with 56 additions and 41 deletions

View file

@ -41,6 +41,11 @@
#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_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_NAME ST_STM32F0_FLASH_CONTROLLER_40022000_LABEL

View file

@ -40,27 +40,6 @@ config CAN_INIT_PRIORITY
Note that the priority needs to be lower than the net stack
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
bool "Enable CAN 1"
default y

View file

@ -94,17 +94,17 @@ static void can_stm32_isr(void *arg)
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);
}
while (can->RF0R & CAN_RF0R_FMP0_Msk) {
while (can->RF0R & CAN_RF0R_FMP0) {
CAN_FIFOMailBox_TypeDef *mbox;
int filter_match_index;
struct can_msg msg;
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);
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;
}
prescaler = clock_rate / (BIT_SEG_LENGTH * cfg->bus_speed);
prescaler = clock_rate / (BIT_SEG_LENGTH(cfg) * bitrate);
if (prescaler == 0 || prescaler > 1024) {
SYS_LOG_ERR("HAL_CAN_Init failed: prescaler > max (%d > 1024)",
prescaler);
return -EINVAL;
}
bs1 = (CONFIG_CAN_PHASE_SEG1_PROP_SEG - 1) << CAN_BTR_TS1_Pos;
bs2 = (CONFIG_CAN_PHASE_SEG2 - 1) << CAN_BTR_TS2_Pos;
swj = (CONFIG_CAN_SJW - 1) << CAN_BTR_SJW_Pos;
if (clock_rate % (BIT_SEG_LENGTH(cfg) * bitrate)) {
SYS_LOG_ERR("Prescaler is not a natural number! "
"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 :
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);
while (!(transmit_status_register & CAN_TSR_TME_Msk)) {
while (!(transmit_status_register & CAN_TSR_TME)) {
k_mutex_unlock(tx_mutex);
SYS_LOG_DBG("Transmit buffer full. Wait with timeout (%dms)",
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->TDTR = (mailbox->TDTR & ~CAN_TDT1R_DLC_Msk) |
mailbox->TDTR = (mailbox->TDTR & ~CAN_TDT1R_DLC) |
((msg->dlc & 0xF) << CAN_TDT1R_DLC_Pos);
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 = {
.can = (CAN_TypeDef *)CONFIG_CAN_1_BASE_ADDRESS,
.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 = {
.enr = RCC_APB1ENR_CANEN,
.bus = STM32_CLOCK_BUS_APB1,

View file

@ -14,8 +14,7 @@
#define DEV_CFG(dev) \
((const struct can_stm32_config *const)(dev)->config->config_info)
#define BIT_SEG_LENGTH ((CONFIG_CAN_PHASE_SEG1_PROP_SEG) \
+ (CONFIG_CAN_PHASE_SEG2) + 1)
#define BIT_SEG_LENGTH(cfg) ((cfg)->prop_bs1 + (cfg)->bs2 + 1)
#define CAN_NUMBER_OF_FILTER_BANKS (14)
#define CAN_MAX_NUMBER_OF_FILTES (CAN_NUMBER_OF_FILTER_BANKS * 4)
@ -68,6 +67,9 @@ struct can_stm32_data {
struct can_stm32_config {
CAN_TypeDef *can; /*!< CAN Registers*/
u32_t bus_speed;
u8_t swj;
u8_t prop_bs1;
u8_t bs2;
struct stm32_pclken pclken;
void (*config_irq)(CAN_TypeDef *can);
};

View file

@ -51,6 +51,10 @@
interrupts = <30 0>;
status = "disabled";
label = "CAN_1";
bus-speed = <250000>;
sjw = <1>;
prop_seg_phase_seg1 = <5>;
phase_seg2 = <6>;
};
};
};

View file

@ -29,9 +29,4 @@ properties:
category: required
description: Human readable string describing the device (used by Zephyr for API name)
generation: define
bus-speed:
type: int
category: required
description: bus spees in Baud/s
generation: define
...

View file

@ -26,7 +26,22 @@ properties:
bus-speed:
type: int
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
pinctrl-\d+:
type: array

View file

@ -1,8 +1,5 @@
CONFIG_CAN=y
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_STM32=y
CONFIG_CAN_MAX_FILTER=5