drivers: can: mcan: move the driver init function to the bottom of the file
Move the driver initialization function to the bottom of the file to be consistent with Zephyr conventions. Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
parent
a3a4144697
commit
df6eda64fb
1 changed files with 172 additions and 172 deletions
|
@ -328,178 +328,6 @@ int can_mcan_set_mode(const struct device *dev, can_mode_t mode)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int can_mcan_init(const struct device *dev)
|
||||
{
|
||||
const struct can_mcan_config *cfg = dev->config;
|
||||
struct can_mcan_data *data = dev->data;
|
||||
struct can_mcan_reg *can = cfg->can;
|
||||
struct can_mcan_msg_sram *msg_ram = data->msg_ram;
|
||||
struct can_timing timing;
|
||||
#ifdef CONFIG_CAN_FD_MODE
|
||||
struct can_timing timing_data;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
k_mutex_init(&data->inst_mutex);
|
||||
k_mutex_init(&data->tx_mtx);
|
||||
k_sem_init(&data->tx_sem, NUM_TX_BUF_ELEMENTS, NUM_TX_BUF_ELEMENTS);
|
||||
|
||||
if (cfg->phy != NULL) {
|
||||
if (!device_is_ready(cfg->phy)) {
|
||||
LOG_ERR("CAN transceiver not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
ret = can_mcan_exit_sleep_mode(dev);
|
||||
if (ret) {
|
||||
LOG_ERR("Failed to exit sleep mode");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ret = can_mcan_enter_init_mode(dev, K_MSEC(CAN_INIT_TIMEOUT));
|
||||
if (ret) {
|
||||
LOG_ERR("Failed to enter init mode");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
can_mcan_enable_configuration_change(dev);
|
||||
|
||||
LOG_DBG("IP rel: %lu.%lu.%lu %02lu.%lu.%lu",
|
||||
(can->crel & CAN_MCAN_CREL_REL) >> CAN_MCAN_CREL_REL_POS,
|
||||
(can->crel & CAN_MCAN_CREL_STEP) >> CAN_MCAN_CREL_STEP_POS,
|
||||
(can->crel & CAN_MCAN_CREL_SUBSTEP) >> CAN_MCAN_CREL_SUBSTEP_POS,
|
||||
(can->crel & CAN_MCAN_CREL_YEAR) >> CAN_MCAN_CREL_YEAR_POS,
|
||||
(can->crel & CAN_MCAN_CREL_MON) >> CAN_MCAN_CREL_MON_POS,
|
||||
(can->crel & CAN_MCAN_CREL_DAY) >> CAN_MCAN_CREL_DAY_POS);
|
||||
|
||||
#ifndef CONFIG_CAN_STM32FD
|
||||
uint32_t mrba = 0;
|
||||
#ifdef CONFIG_CAN_STM32H7
|
||||
mrba = (uint32_t)msg_ram;
|
||||
#endif
|
||||
#ifdef CONFIG_CAN_MCUX_MCAN
|
||||
mrba = (uint32_t)msg_ram & CAN_MCAN_MRBA_BA_MSK;
|
||||
can->mrba = mrba;
|
||||
#endif
|
||||
can->sidfc = (((uint32_t)msg_ram->std_filt - mrba) & CAN_MCAN_SIDFC_FLSSA_MSK) |
|
||||
(ARRAY_SIZE(msg_ram->std_filt) << CAN_MCAN_SIDFC_LSS_POS);
|
||||
can->xidfc = (((uint32_t)msg_ram->ext_filt - mrba) & CAN_MCAN_XIDFC_FLESA_MSK) |
|
||||
(ARRAY_SIZE(msg_ram->ext_filt) << CAN_MCAN_XIDFC_LSS_POS);
|
||||
can->rxf0c = (((uint32_t)msg_ram->rx_fifo0 - mrba) & CAN_MCAN_RXF0C_F0SA) |
|
||||
(ARRAY_SIZE(msg_ram->rx_fifo0) << CAN_MCAN_RXF0C_F0S_POS);
|
||||
can->rxf1c = (((uint32_t)msg_ram->rx_fifo1 - mrba) & CAN_MCAN_RXF1C_F1SA) |
|
||||
(ARRAY_SIZE(msg_ram->rx_fifo1) << CAN_MCAN_RXF1C_F1S_POS);
|
||||
can->rxbc = (((uint32_t)msg_ram->rx_buffer - mrba) & CAN_MCAN_RXBC_RBSA);
|
||||
can->txefc = (((uint32_t)msg_ram->tx_event_fifo - mrba) & CAN_MCAN_TXEFC_EFSA_MSK) |
|
||||
(ARRAY_SIZE(msg_ram->tx_event_fifo) << CAN_MCAN_TXEFC_EFS_POS);
|
||||
can->txbc = (((uint32_t)msg_ram->tx_buffer - mrba) & CAN_MCAN_TXBC_TBSA) |
|
||||
(ARRAY_SIZE(msg_ram->tx_buffer) << CAN_MCAN_TXBC_TFQS_POS) | CAN_MCAN_TXBC_TFQM;
|
||||
|
||||
if (sizeof(msg_ram->tx_buffer[0].data) <= 24) {
|
||||
can->txesc = (sizeof(msg_ram->tx_buffer[0].data) - 8) / 4;
|
||||
} else {
|
||||
can->txesc = (sizeof(msg_ram->tx_buffer[0].data) - 32) / 16 + 5;
|
||||
}
|
||||
|
||||
if (sizeof(msg_ram->rx_fifo0[0].data) <= 24) {
|
||||
can->rxesc =
|
||||
(((sizeof(msg_ram->rx_fifo0[0].data) - 8) / 4) << CAN_MCAN_RXESC_F0DS_POS) |
|
||||
(((sizeof(msg_ram->rx_fifo1[0].data) - 8) / 4) << CAN_MCAN_RXESC_F1DS_POS) |
|
||||
(((sizeof(msg_ram->rx_buffer[0].data) - 8) / 4) << CAN_MCAN_RXESC_RBDS_POS);
|
||||
} else {
|
||||
can->rxesc = (((sizeof(msg_ram->rx_fifo0[0].data) - 32) / 16 + 5)
|
||||
<< CAN_MCAN_RXESC_F0DS_POS) |
|
||||
(((sizeof(msg_ram->rx_fifo1[0].data) - 32) / 16 + 5)
|
||||
<< CAN_MCAN_RXESC_F1DS_POS) |
|
||||
(((sizeof(msg_ram->rx_buffer[0].data) - 32) / 16 + 5)
|
||||
<< CAN_MCAN_RXESC_RBDS_POS);
|
||||
}
|
||||
#endif
|
||||
can->cccr &= ~(CAN_MCAN_CCCR_FDOE | CAN_MCAN_CCCR_BRSE | CAN_MCAN_CCCR_TEST |
|
||||
CAN_MCAN_CCCR_MON | CAN_MCAN_CCCR_ASM);
|
||||
can->test &= ~(CAN_MCAN_TEST_LBCK);
|
||||
|
||||
#if defined(CONFIG_CAN_DELAY_COMP) && defined(CONFIG_CAN_FD_MODE)
|
||||
can->dbtp |= CAN_MCAN_DBTP_TDC;
|
||||
can->tdcr |= cfg->tx_delay_comp_offset << CAN_MCAN_TDCR_TDCO_POS;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CAN_STM32FD
|
||||
can->rxgfc |= (CONFIG_CAN_MAX_STD_ID_FILTER << CAN_MCAN_RXGFC_LSS_POS) |
|
||||
(CONFIG_CAN_MAX_EXT_ID_FILTER << CAN_MCAN_RXGFC_LSE_POS) |
|
||||
(0x2 << CAN_MCAN_RXGFC_ANFS_POS) | (0x2 << CAN_MCAN_RXGFC_ANFE_POS);
|
||||
#else
|
||||
can->gfc |= (0x2 << CAN_MCAN_GFC_ANFE_POS) | (0x2 << CAN_MCAN_GFC_ANFS_POS);
|
||||
#endif /* CONFIG_CAN_STM32FD */
|
||||
|
||||
if (cfg->sample_point) {
|
||||
ret = can_calc_timing(dev, &timing, cfg->bus_speed, cfg->sample_point);
|
||||
if (ret == -EINVAL) {
|
||||
LOG_ERR("Can't find timing for given param");
|
||||
return -EIO;
|
||||
}
|
||||
LOG_DBG("Presc: %d, TS1: %d, TS2: %d", timing.prescaler, timing.phase_seg1,
|
||||
timing.phase_seg2);
|
||||
LOG_DBG("Sample-point err : %d", ret);
|
||||
} else if (cfg->prop_ts1) {
|
||||
timing.prop_seg = 0;
|
||||
timing.phase_seg1 = cfg->prop_ts1;
|
||||
timing.phase_seg2 = cfg->ts2;
|
||||
ret = can_calc_prescaler(dev, &timing, cfg->bus_speed);
|
||||
if (ret) {
|
||||
LOG_WRN("Bitrate error: %d", ret);
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_CAN_FD_MODE
|
||||
if (cfg->sample_point_data) {
|
||||
ret = can_calc_timing_data(dev, &timing_data, cfg->bus_speed_data,
|
||||
cfg->sample_point_data);
|
||||
if (ret == -EINVAL) {
|
||||
LOG_ERR("Can't find timing for given dataphase param");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
LOG_DBG("Sample-point err data phase: %d", ret);
|
||||
} else if (cfg->prop_ts1_data) {
|
||||
timing_data.prop_seg = 0;
|
||||
timing_data.phase_seg1 = cfg->prop_ts1_data;
|
||||
timing_data.phase_seg2 = cfg->ts2_data;
|
||||
ret = can_calc_prescaler(dev, &timing_data, cfg->bus_speed_data);
|
||||
if (ret) {
|
||||
LOG_WRN("Dataphase bitrate error: %d", ret);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
timing.sjw = cfg->sjw;
|
||||
#ifdef CONFIG_CAN_FD_MODE
|
||||
timing_data.sjw = cfg->sjw_data;
|
||||
can_mcan_configure_timing(dev, &timing, &timing_data);
|
||||
#else
|
||||
can_mcan_configure_timing(dev, &timing, NULL);
|
||||
#endif
|
||||
|
||||
can->ie = CAN_MCAN_IE_BO | CAN_MCAN_IE_EW | CAN_MCAN_IE_EP | CAN_MCAN_IE_MRAF |
|
||||
CAN_MCAN_IE_TEFL | CAN_MCAN_IE_TEFN | CAN_MCAN_IE_RF0N | CAN_MCAN_IE_RF1N |
|
||||
CAN_MCAN_IE_RF0L | CAN_MCAN_IE_RF1L;
|
||||
|
||||
#ifdef CONFIG_CAN_STM32FD
|
||||
can->ils = CAN_MCAN_ILS_RXFIFO0 | CAN_MCAN_ILS_RXFIFO1;
|
||||
#else
|
||||
can->ils = CAN_MCAN_ILS_RF0N | CAN_MCAN_ILS_RF1N;
|
||||
#endif
|
||||
can->ile = CAN_MCAN_ILE_EINT0 | CAN_MCAN_ILE_EINT1;
|
||||
/* Interrupt on every TX fifo element*/
|
||||
can->txbtie = CAN_MCAN_TXBTIE_TIE;
|
||||
|
||||
memset32_volatile(msg_ram, 0, sizeof(struct can_mcan_msg_sram));
|
||||
sys_cache_data_flush_range(msg_ram, sizeof(struct can_mcan_msg_sram));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void can_mcan_state_change_handler(const struct device *dev)
|
||||
{
|
||||
struct can_mcan_data *data = dev->data;
|
||||
|
@ -1111,3 +939,175 @@ void can_mcan_enable_configuration_change(const struct device *dev)
|
|||
|
||||
can->cccr |= CAN_MCAN_CCCR_CCE;
|
||||
}
|
||||
|
||||
int can_mcan_init(const struct device *dev)
|
||||
{
|
||||
const struct can_mcan_config *cfg = dev->config;
|
||||
struct can_mcan_data *data = dev->data;
|
||||
struct can_mcan_reg *can = cfg->can;
|
||||
struct can_mcan_msg_sram *msg_ram = data->msg_ram;
|
||||
struct can_timing timing;
|
||||
#ifdef CONFIG_CAN_FD_MODE
|
||||
struct can_timing timing_data;
|
||||
#endif
|
||||
int ret;
|
||||
|
||||
k_mutex_init(&data->inst_mutex);
|
||||
k_mutex_init(&data->tx_mtx);
|
||||
k_sem_init(&data->tx_sem, NUM_TX_BUF_ELEMENTS, NUM_TX_BUF_ELEMENTS);
|
||||
|
||||
if (cfg->phy != NULL) {
|
||||
if (!device_is_ready(cfg->phy)) {
|
||||
LOG_ERR("CAN transceiver not ready");
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
ret = can_mcan_exit_sleep_mode(dev);
|
||||
if (ret) {
|
||||
LOG_ERR("Failed to exit sleep mode");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
ret = can_mcan_enter_init_mode(dev, K_MSEC(CAN_INIT_TIMEOUT));
|
||||
if (ret) {
|
||||
LOG_ERR("Failed to enter init mode");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
can_mcan_enable_configuration_change(dev);
|
||||
|
||||
LOG_DBG("IP rel: %lu.%lu.%lu %02lu.%lu.%lu",
|
||||
(can->crel & CAN_MCAN_CREL_REL) >> CAN_MCAN_CREL_REL_POS,
|
||||
(can->crel & CAN_MCAN_CREL_STEP) >> CAN_MCAN_CREL_STEP_POS,
|
||||
(can->crel & CAN_MCAN_CREL_SUBSTEP) >> CAN_MCAN_CREL_SUBSTEP_POS,
|
||||
(can->crel & CAN_MCAN_CREL_YEAR) >> CAN_MCAN_CREL_YEAR_POS,
|
||||
(can->crel & CAN_MCAN_CREL_MON) >> CAN_MCAN_CREL_MON_POS,
|
||||
(can->crel & CAN_MCAN_CREL_DAY) >> CAN_MCAN_CREL_DAY_POS);
|
||||
|
||||
#ifndef CONFIG_CAN_STM32FD
|
||||
uint32_t mrba = 0;
|
||||
#ifdef CONFIG_CAN_STM32H7
|
||||
mrba = (uint32_t)msg_ram;
|
||||
#endif
|
||||
#ifdef CONFIG_CAN_MCUX_MCAN
|
||||
mrba = (uint32_t)msg_ram & CAN_MCAN_MRBA_BA_MSK;
|
||||
can->mrba = mrba;
|
||||
#endif
|
||||
can->sidfc = (((uint32_t)msg_ram->std_filt - mrba) & CAN_MCAN_SIDFC_FLSSA_MSK) |
|
||||
(ARRAY_SIZE(msg_ram->std_filt) << CAN_MCAN_SIDFC_LSS_POS);
|
||||
can->xidfc = (((uint32_t)msg_ram->ext_filt - mrba) & CAN_MCAN_XIDFC_FLESA_MSK) |
|
||||
(ARRAY_SIZE(msg_ram->ext_filt) << CAN_MCAN_XIDFC_LSS_POS);
|
||||
can->rxf0c = (((uint32_t)msg_ram->rx_fifo0 - mrba) & CAN_MCAN_RXF0C_F0SA) |
|
||||
(ARRAY_SIZE(msg_ram->rx_fifo0) << CAN_MCAN_RXF0C_F0S_POS);
|
||||
can->rxf1c = (((uint32_t)msg_ram->rx_fifo1 - mrba) & CAN_MCAN_RXF1C_F1SA) |
|
||||
(ARRAY_SIZE(msg_ram->rx_fifo1) << CAN_MCAN_RXF1C_F1S_POS);
|
||||
can->rxbc = (((uint32_t)msg_ram->rx_buffer - mrba) & CAN_MCAN_RXBC_RBSA);
|
||||
can->txefc = (((uint32_t)msg_ram->tx_event_fifo - mrba) & CAN_MCAN_TXEFC_EFSA_MSK) |
|
||||
(ARRAY_SIZE(msg_ram->tx_event_fifo) << CAN_MCAN_TXEFC_EFS_POS);
|
||||
can->txbc = (((uint32_t)msg_ram->tx_buffer - mrba) & CAN_MCAN_TXBC_TBSA) |
|
||||
(ARRAY_SIZE(msg_ram->tx_buffer) << CAN_MCAN_TXBC_TFQS_POS) | CAN_MCAN_TXBC_TFQM;
|
||||
|
||||
if (sizeof(msg_ram->tx_buffer[0].data) <= 24) {
|
||||
can->txesc = (sizeof(msg_ram->tx_buffer[0].data) - 8) / 4;
|
||||
} else {
|
||||
can->txesc = (sizeof(msg_ram->tx_buffer[0].data) - 32) / 16 + 5;
|
||||
}
|
||||
|
||||
if (sizeof(msg_ram->rx_fifo0[0].data) <= 24) {
|
||||
can->rxesc =
|
||||
(((sizeof(msg_ram->rx_fifo0[0].data) - 8) / 4) << CAN_MCAN_RXESC_F0DS_POS) |
|
||||
(((sizeof(msg_ram->rx_fifo1[0].data) - 8) / 4) << CAN_MCAN_RXESC_F1DS_POS) |
|
||||
(((sizeof(msg_ram->rx_buffer[0].data) - 8) / 4) << CAN_MCAN_RXESC_RBDS_POS);
|
||||
} else {
|
||||
can->rxesc = (((sizeof(msg_ram->rx_fifo0[0].data) - 32) / 16 + 5)
|
||||
<< CAN_MCAN_RXESC_F0DS_POS) |
|
||||
(((sizeof(msg_ram->rx_fifo1[0].data) - 32) / 16 + 5)
|
||||
<< CAN_MCAN_RXESC_F1DS_POS) |
|
||||
(((sizeof(msg_ram->rx_buffer[0].data) - 32) / 16 + 5)
|
||||
<< CAN_MCAN_RXESC_RBDS_POS);
|
||||
}
|
||||
#endif
|
||||
can->cccr &= ~(CAN_MCAN_CCCR_FDOE | CAN_MCAN_CCCR_BRSE | CAN_MCAN_CCCR_TEST |
|
||||
CAN_MCAN_CCCR_MON | CAN_MCAN_CCCR_ASM);
|
||||
can->test &= ~(CAN_MCAN_TEST_LBCK);
|
||||
|
||||
#if defined(CONFIG_CAN_DELAY_COMP) && defined(CONFIG_CAN_FD_MODE)
|
||||
can->dbtp |= CAN_MCAN_DBTP_TDC;
|
||||
can->tdcr |= cfg->tx_delay_comp_offset << CAN_MCAN_TDCR_TDCO_POS;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CAN_STM32FD
|
||||
can->rxgfc |= (CONFIG_CAN_MAX_STD_ID_FILTER << CAN_MCAN_RXGFC_LSS_POS) |
|
||||
(CONFIG_CAN_MAX_EXT_ID_FILTER << CAN_MCAN_RXGFC_LSE_POS) |
|
||||
(0x2 << CAN_MCAN_RXGFC_ANFS_POS) | (0x2 << CAN_MCAN_RXGFC_ANFE_POS);
|
||||
#else
|
||||
can->gfc |= (0x2 << CAN_MCAN_GFC_ANFE_POS) | (0x2 << CAN_MCAN_GFC_ANFS_POS);
|
||||
#endif /* CONFIG_CAN_STM32FD */
|
||||
|
||||
if (cfg->sample_point) {
|
||||
ret = can_calc_timing(dev, &timing, cfg->bus_speed, cfg->sample_point);
|
||||
if (ret == -EINVAL) {
|
||||
LOG_ERR("Can't find timing for given param");
|
||||
return -EIO;
|
||||
}
|
||||
LOG_DBG("Presc: %d, TS1: %d, TS2: %d", timing.prescaler, timing.phase_seg1,
|
||||
timing.phase_seg2);
|
||||
LOG_DBG("Sample-point err : %d", ret);
|
||||
} else if (cfg->prop_ts1) {
|
||||
timing.prop_seg = 0;
|
||||
timing.phase_seg1 = cfg->prop_ts1;
|
||||
timing.phase_seg2 = cfg->ts2;
|
||||
ret = can_calc_prescaler(dev, &timing, cfg->bus_speed);
|
||||
if (ret) {
|
||||
LOG_WRN("Bitrate error: %d", ret);
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_CAN_FD_MODE
|
||||
if (cfg->sample_point_data) {
|
||||
ret = can_calc_timing_data(dev, &timing_data, cfg->bus_speed_data,
|
||||
cfg->sample_point_data);
|
||||
if (ret == -EINVAL) {
|
||||
LOG_ERR("Can't find timing for given dataphase param");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
LOG_DBG("Sample-point err data phase: %d", ret);
|
||||
} else if (cfg->prop_ts1_data) {
|
||||
timing_data.prop_seg = 0;
|
||||
timing_data.phase_seg1 = cfg->prop_ts1_data;
|
||||
timing_data.phase_seg2 = cfg->ts2_data;
|
||||
ret = can_calc_prescaler(dev, &timing_data, cfg->bus_speed_data);
|
||||
if (ret) {
|
||||
LOG_WRN("Dataphase bitrate error: %d", ret);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
timing.sjw = cfg->sjw;
|
||||
#ifdef CONFIG_CAN_FD_MODE
|
||||
timing_data.sjw = cfg->sjw_data;
|
||||
can_mcan_configure_timing(dev, &timing, &timing_data);
|
||||
#else
|
||||
can_mcan_configure_timing(dev, &timing, NULL);
|
||||
#endif
|
||||
|
||||
can->ie = CAN_MCAN_IE_BO | CAN_MCAN_IE_EW | CAN_MCAN_IE_EP | CAN_MCAN_IE_MRAF |
|
||||
CAN_MCAN_IE_TEFL | CAN_MCAN_IE_TEFN | CAN_MCAN_IE_RF0N | CAN_MCAN_IE_RF1N |
|
||||
CAN_MCAN_IE_RF0L | CAN_MCAN_IE_RF1L;
|
||||
|
||||
#ifdef CONFIG_CAN_STM32FD
|
||||
can->ils = CAN_MCAN_ILS_RXFIFO0 | CAN_MCAN_ILS_RXFIFO1;
|
||||
#else
|
||||
can->ils = CAN_MCAN_ILS_RF0N | CAN_MCAN_ILS_RF1N;
|
||||
#endif
|
||||
can->ile = CAN_MCAN_ILE_EINT0 | CAN_MCAN_ILE_EINT1;
|
||||
/* Interrupt on every TX fifo element*/
|
||||
can->txbtie = CAN_MCAN_TXBTIE_TIE;
|
||||
|
||||
memset32_volatile(msg_ram, 0, sizeof(struct can_mcan_msg_sram));
|
||||
sys_cache_data_flush_range(msg_ram, sizeof(struct can_mcan_msg_sram));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue