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_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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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
|
||||
...
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue