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_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

View file

@ -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

View file

@ -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,

View file

@ -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);
}; };

View file

@ -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>;
}; };
}; };
}; };

View file

@ -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
... ...

View file

@ -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

View file

@ -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