drivers: can: mcan: use per-instance message RAM configuration
Restructure the Bosch M_CAN driver backend to use per-instance Message RAM configuration. This removes the need for a common, artificial "can" devicetree node for SoCs with multiple Bosch M_CAN-based CAN controllers and allows for per-instance configuration of the number of e.g. standard (11-bit) and extended (29-bit) filter elements. As part of the restructure, software handling of CAN filter flags was moved from per-flags bitfields to per-filter bitfields, solving an issue when using more than 32 standard (11-bit) filter elements or more than 16 extended (29-bit) filter elements. Fixes: #42030, #53417 Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
This commit is contained in:
parent
d112e08f0c
commit
0f36f1a3ee
24 changed files with 878 additions and 546 deletions
|
@ -342,6 +342,7 @@ int can_mcan_start(const struct device *dev)
|
||||||
int can_mcan_stop(const struct device *dev)
|
int can_mcan_stop(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct can_mcan_config *config = dev->config;
|
const struct can_mcan_config *config = dev->config;
|
||||||
|
const struct can_mcan_callbacks *cbs = config->callbacks;
|
||||||
struct can_mcan_data *data = dev->data;
|
struct can_mcan_data *data = dev->data;
|
||||||
can_tx_callback_t tx_cb;
|
can_tx_callback_t tx_cb;
|
||||||
uint32_t tx_idx;
|
uint32_t tx_idx;
|
||||||
|
@ -370,12 +371,12 @@ int can_mcan_stop(const struct device *dev)
|
||||||
|
|
||||||
data->started = false;
|
data->started = false;
|
||||||
|
|
||||||
for (tx_idx = 0U; tx_idx < ARRAY_SIZE(data->tx_fin_cb); tx_idx++) {
|
for (tx_idx = 0U; tx_idx < cbs->num_tx; tx_idx++) {
|
||||||
tx_cb = data->tx_fin_cb[tx_idx];
|
tx_cb = cbs->tx[tx_idx].function;
|
||||||
|
|
||||||
if (tx_cb != NULL) {
|
if (tx_cb != NULL) {
|
||||||
data->tx_fin_cb[tx_idx] = NULL;
|
cbs->tx[tx_idx].function = NULL;
|
||||||
tx_cb(dev, -ENETDOWN, data->tx_fin_cb_arg[tx_idx]);
|
tx_cb(dev, -ENETDOWN, cbs->tx[tx_idx].user_data);
|
||||||
k_sem_give(&data->tx_sem);
|
k_sem_give(&data->tx_sem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -476,6 +477,8 @@ static void can_mcan_state_change_handler(const struct device *dev)
|
||||||
|
|
||||||
static void can_mcan_tc_event_handler(const struct device *dev)
|
static void can_mcan_tc_event_handler(const struct device *dev)
|
||||||
{
|
{
|
||||||
|
const struct can_mcan_config *config = dev->config;
|
||||||
|
const struct can_mcan_callbacks *cbs = config->callbacks;
|
||||||
struct can_mcan_data *data = dev->data;
|
struct can_mcan_data *data = dev->data;
|
||||||
struct can_mcan_tx_event_fifo tx_event;
|
struct can_mcan_tx_event_fifo tx_event;
|
||||||
can_tx_callback_t tx_cb;
|
can_tx_callback_t tx_cb;
|
||||||
|
@ -491,7 +494,8 @@ static void can_mcan_tc_event_handler(const struct device *dev)
|
||||||
|
|
||||||
while ((txefs & CAN_MCAN_TXEFS_EFFL) != 0U) {
|
while ((txefs & CAN_MCAN_TXEFS_EFFL) != 0U) {
|
||||||
event_idx = FIELD_GET(CAN_MCAN_TXEFS_EFGI, txefs);
|
event_idx = FIELD_GET(CAN_MCAN_TXEFS_EFGI, txefs);
|
||||||
err = can_mcan_read_mram(dev, CAN_MCAN_MRAM_OFFSET_TX_EVENT_FIFO +
|
err = can_mcan_read_mram(dev,
|
||||||
|
config->mram_offsets[CAN_MCAN_MRAM_CFG_TX_EVENT_FIFO] +
|
||||||
event_idx * sizeof(struct can_mcan_tx_event_fifo),
|
event_idx * sizeof(struct can_mcan_tx_event_fifo),
|
||||||
&tx_event,
|
&tx_event,
|
||||||
sizeof(struct can_mcan_tx_event_fifo));
|
sizeof(struct can_mcan_tx_event_fifo));
|
||||||
|
@ -510,9 +514,10 @@ static void can_mcan_tc_event_handler(const struct device *dev)
|
||||||
|
|
||||||
k_sem_give(&data->tx_sem);
|
k_sem_give(&data->tx_sem);
|
||||||
|
|
||||||
tx_cb = data->tx_fin_cb[tx_idx];
|
__ASSERT_NO_MSG(tx_idx <= cbs->num_tx);
|
||||||
data->tx_fin_cb[tx_idx] = NULL;
|
tx_cb = cbs->tx[tx_idx].function;
|
||||||
tx_cb(dev, 0, data->tx_fin_cb_arg[tx_idx]);
|
cbs->tx[tx_idx].function = NULL;
|
||||||
|
tx_cb(dev, 0, cbs->tx[tx_idx].user_data);
|
||||||
|
|
||||||
err = can_mcan_read_reg(dev, CAN_MCAN_TXEFS, &txefs);
|
err = can_mcan_read_reg(dev, CAN_MCAN_TXEFS, &txefs);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
|
@ -573,16 +578,16 @@ void can_mcan_line_0_isr(const struct device *dev)
|
||||||
static void can_mcan_get_message(const struct device *dev, uint16_t fifo_offset,
|
static void can_mcan_get_message(const struct device *dev, uint16_t fifo_offset,
|
||||||
uint16_t fifo_status_reg, uint16_t fifo_ack_reg)
|
uint16_t fifo_status_reg, uint16_t fifo_ack_reg)
|
||||||
{
|
{
|
||||||
struct can_mcan_data *data = dev->data;
|
const struct can_mcan_config *config = dev->config;
|
||||||
uint32_t get_idx, filt_idx;
|
const struct can_mcan_callbacks *cbs = config->callbacks;
|
||||||
|
struct can_mcan_rx_fifo_hdr hdr;
|
||||||
struct can_frame frame = {0};
|
struct can_frame frame = {0};
|
||||||
can_rx_callback_t cb;
|
can_rx_callback_t cb;
|
||||||
|
void *user_data;
|
||||||
|
uint8_t flags;
|
||||||
|
uint32_t get_idx;
|
||||||
|
uint32_t filt_idx;
|
||||||
int data_length;
|
int data_length;
|
||||||
void *cb_arg;
|
|
||||||
struct can_mcan_rx_fifo_hdr hdr;
|
|
||||||
bool rtr_filter_mask;
|
|
||||||
bool rtr_filter;
|
|
||||||
bool fd_frame_filter;
|
|
||||||
uint32_t fifo_status;
|
uint32_t fifo_status;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -630,25 +635,25 @@ static void can_mcan_get_message(const struct device *dev, uint16_t fifo_offset,
|
||||||
if (hdr.xtd != 0) {
|
if (hdr.xtd != 0) {
|
||||||
frame.id = hdr.ext_id;
|
frame.id = hdr.ext_id;
|
||||||
frame.flags |= CAN_FRAME_IDE;
|
frame.flags |= CAN_FRAME_IDE;
|
||||||
rtr_filter_mask = (data->ext_filt_rtr_mask & BIT(filt_idx)) != 0U;
|
flags = cbs->ext[filt_idx].flags;
|
||||||
rtr_filter = (data->ext_filt_rtr & BIT(filt_idx)) != 0;
|
|
||||||
fd_frame_filter = (data->ext_filt_fd_frame & BIT(filt_idx)) != 0U;
|
|
||||||
} else {
|
} else {
|
||||||
frame.id = hdr.std_id;
|
frame.id = hdr.std_id;
|
||||||
rtr_filter_mask = (data->std_filt_rtr_mask & BIT(filt_idx)) != 0U;
|
flags = cbs->std[filt_idx].flags;
|
||||||
rtr_filter = (data->std_filt_rtr & BIT(filt_idx)) != 0;
|
|
||||||
fd_frame_filter = (data->std_filt_fd_frame & BIT(filt_idx)) != 0U;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rtr_filter_mask && (rtr_filter != ((frame.flags & CAN_FRAME_RTR) != 0U))) {
|
if (((frame.flags & CAN_FRAME_RTR) == 0U && (flags & CAN_FILTER_DATA) == 0U) ||
|
||||||
/* RTR bit does not match filter RTR mask, drop frame */
|
((frame.flags & CAN_FRAME_RTR) != 0U && (flags & CAN_FILTER_RTR) == 0U)) {
|
||||||
|
/* RTR bit does not match filter, drop frame */
|
||||||
err = can_mcan_write_reg(dev, fifo_ack_reg, get_idx);
|
err = can_mcan_write_reg(dev, fifo_ack_reg, get_idx);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
goto ack;
|
goto ack;
|
||||||
} else if (fd_frame_filter != ((frame.flags & CAN_FRAME_FDF) != 0U)) {
|
}
|
||||||
/* FD bit does not match filter FD frame, drop frame */
|
|
||||||
|
if (((frame.flags & CAN_FRAME_FDF) != 0U && (flags & CAN_FILTER_FDF) == 0U) ||
|
||||||
|
((frame.flags & CAN_FRAME_FDF) == 0U && (flags & CAN_FILTER_FDF) != 0U)) {
|
||||||
|
/* FDF bit does not match filter, drop frame */
|
||||||
err = can_mcan_write_reg(dev, fifo_ack_reg, get_idx);
|
err = can_mcan_write_reg(dev, fifo_ack_reg, get_idx);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -670,17 +675,19 @@ static void can_mcan_get_message(const struct device *dev, uint16_t fifo_offset,
|
||||||
|
|
||||||
if ((frame.flags & CAN_FRAME_IDE) != 0) {
|
if ((frame.flags & CAN_FRAME_IDE) != 0) {
|
||||||
LOG_DBG("Frame on filter %d, ID: 0x%x",
|
LOG_DBG("Frame on filter %d, ID: 0x%x",
|
||||||
filt_idx + NUM_STD_FILTER_DATA, frame.id);
|
filt_idx + cbs->num_std, frame.id);
|
||||||
cb = data->rx_cb_ext[filt_idx];
|
__ASSERT_NO_MSG(filt_idx <= cbs->num_ext);
|
||||||
cb_arg = data->cb_arg_ext[filt_idx];
|
cb = cbs->ext[filt_idx].function;
|
||||||
|
user_data = cbs->ext[filt_idx].user_data;
|
||||||
} else {
|
} else {
|
||||||
LOG_DBG("Frame on filter %d, ID: 0x%x", filt_idx, frame.id);
|
LOG_DBG("Frame on filter %d, ID: 0x%x", filt_idx, frame.id);
|
||||||
cb = data->rx_cb_std[filt_idx];
|
__ASSERT_NO_MSG(filt_idx <= cbs->num_std);
|
||||||
cb_arg = data->cb_arg_std[filt_idx];
|
cb = cbs->std[filt_idx].function;
|
||||||
|
user_data = cbs->std[filt_idx].user_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cb) {
|
if (cb) {
|
||||||
cb(dev, &frame, cb_arg);
|
cb(dev, &frame, user_data);
|
||||||
} else {
|
} else {
|
||||||
LOG_DBG("cb missing");
|
LOG_DBG("cb missing");
|
||||||
}
|
}
|
||||||
|
@ -703,6 +710,7 @@ ack:
|
||||||
|
|
||||||
void can_mcan_line_1_isr(const struct device *dev)
|
void can_mcan_line_1_isr(const struct device *dev)
|
||||||
{
|
{
|
||||||
|
const struct can_mcan_config *config = dev->config;
|
||||||
const uint32_t events =
|
const uint32_t events =
|
||||||
CAN_MCAN_IR_RF0N | CAN_MCAN_IR_RF1N | CAN_MCAN_IR_RF0L | CAN_MCAN_IR_RF1L;
|
CAN_MCAN_IR_RF0N | CAN_MCAN_IR_RF1N | CAN_MCAN_IR_RF0L | CAN_MCAN_IR_RF1L;
|
||||||
uint32_t ir;
|
uint32_t ir;
|
||||||
|
@ -716,14 +724,14 @@ void can_mcan_line_1_isr(const struct device *dev)
|
||||||
while ((ir & events) != 0U) {
|
while ((ir & events) != 0U) {
|
||||||
if ((ir & CAN_MCAN_IR_RF0N) != 0U) {
|
if ((ir & CAN_MCAN_IR_RF0N) != 0U) {
|
||||||
LOG_DBG("RX FIFO0 INT");
|
LOG_DBG("RX FIFO0 INT");
|
||||||
can_mcan_get_message(dev, CAN_MCAN_MRAM_OFFSET_RX_FIFO0, CAN_MCAN_RXF0S,
|
can_mcan_get_message(dev, config->mram_offsets[CAN_MCAN_MRAM_CFG_RX_FIFO0],
|
||||||
CAN_MCAN_RXF0A);
|
CAN_MCAN_RXF0S, CAN_MCAN_RXF0A);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ir & CAN_MCAN_IR_RF1N) != 0U) {
|
if ((ir & CAN_MCAN_IR_RF1N) != 0U) {
|
||||||
LOG_DBG("RX FIFO1 INT");
|
LOG_DBG("RX FIFO1 INT");
|
||||||
can_mcan_get_message(dev, CAN_MCAN_MRAM_OFFSET_RX_FIFO1, CAN_MCAN_RXF1S,
|
can_mcan_get_message(dev, config->mram_offsets[CAN_MCAN_MRAM_CFG_RX_FIFO1],
|
||||||
CAN_MCAN_RXF1A);
|
CAN_MCAN_RXF1S, CAN_MCAN_RXF1A);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ir & CAN_MCAN_IR_RF0L) != 0U) {
|
if ((ir & CAN_MCAN_IR_RF0L) != 0U) {
|
||||||
|
@ -801,6 +809,8 @@ int can_mcan_recover(const struct device *dev, k_timeout_t timeout)
|
||||||
int can_mcan_send(const struct device *dev, const struct can_frame *frame, k_timeout_t timeout,
|
int can_mcan_send(const struct device *dev, const struct can_frame *frame, k_timeout_t timeout,
|
||||||
can_tx_callback_t callback, void *user_data)
|
can_tx_callback_t callback, void *user_data)
|
||||||
{
|
{
|
||||||
|
const struct can_mcan_config *config = dev->config;
|
||||||
|
const struct can_mcan_callbacks *cbs = config->callbacks;
|
||||||
struct can_mcan_data *data = dev->data;
|
struct can_mcan_data *data = dev->data;
|
||||||
size_t data_length = can_dlc_to_bytes(frame->dlc);
|
size_t data_length = can_dlc_to_bytes(frame->dlc);
|
||||||
struct can_mcan_tx_buffer_hdr tx_hdr = {
|
struct can_mcan_tx_buffer_hdr tx_hdr = {
|
||||||
|
@ -901,7 +911,7 @@ int can_mcan_send(const struct device *dev, const struct can_frame *frame, k_tim
|
||||||
tx_hdr.std_id = frame->id & CAN_STD_ID_MASK;
|
tx_hdr.std_id = frame->id & CAN_STD_ID_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = can_mcan_write_mram(dev, CAN_MCAN_MRAM_OFFSET_TX_BUFFER + put_idx *
|
err = can_mcan_write_mram(dev, config->mram_offsets[CAN_MCAN_MRAM_CFG_TX_BUFFER] + put_idx *
|
||||||
sizeof(struct can_mcan_tx_buffer) +
|
sizeof(struct can_mcan_tx_buffer) +
|
||||||
offsetof(struct can_mcan_tx_buffer, hdr),
|
offsetof(struct can_mcan_tx_buffer, hdr),
|
||||||
&tx_hdr, sizeof(struct can_mcan_tx_buffer_hdr));
|
&tx_hdr, sizeof(struct can_mcan_tx_buffer_hdr));
|
||||||
|
@ -910,7 +920,7 @@ int can_mcan_send(const struct device *dev, const struct can_frame *frame, k_tim
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = can_mcan_write_mram(dev, CAN_MCAN_MRAM_OFFSET_TX_BUFFER + put_idx *
|
err = can_mcan_write_mram(dev, config->mram_offsets[CAN_MCAN_MRAM_CFG_TX_BUFFER] + put_idx *
|
||||||
sizeof(struct can_mcan_tx_buffer) +
|
sizeof(struct can_mcan_tx_buffer) +
|
||||||
offsetof(struct can_mcan_tx_buffer, data_32),
|
offsetof(struct can_mcan_tx_buffer, data_32),
|
||||||
&frame->data_32, ROUND_UP(data_length, sizeof(uint32_t)));
|
&frame->data_32, ROUND_UP(data_length, sizeof(uint32_t)));
|
||||||
|
@ -919,8 +929,9 @@ int can_mcan_send(const struct device *dev, const struct can_frame *frame, k_tim
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
data->tx_fin_cb[put_idx] = callback;
|
__ASSERT_NO_MSG(put_idx <= cbs->num_tx);
|
||||||
data->tx_fin_cb_arg[put_idx] = user_data;
|
cbs->tx[put_idx].function = callback;
|
||||||
|
cbs->tx[put_idx].user_data = user_data;
|
||||||
|
|
||||||
err = can_mcan_write_reg(dev, CAN_MCAN_TXBAR, BIT(put_idx));
|
err = can_mcan_write_reg(dev, CAN_MCAN_TXBAR, BIT(put_idx));
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
|
@ -935,12 +946,14 @@ unlock:
|
||||||
|
|
||||||
static int can_mcan_get_free_std(const struct device *dev)
|
static int can_mcan_get_free_std(const struct device *dev)
|
||||||
{
|
{
|
||||||
|
const struct can_mcan_config *config = dev->config;
|
||||||
|
const struct can_mcan_callbacks *cbs = config->callbacks;
|
||||||
struct can_mcan_std_filter filter;
|
struct can_mcan_std_filter filter;
|
||||||
int err;
|
int err;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < NUM_STD_FILTER_DATA; ++i) {
|
for (i = 0; i < cbs->num_std; ++i) {
|
||||||
err = can_mcan_read_mram(dev, CAN_MCAN_MRAM_OFFSET_STD_FILTER +
|
err = can_mcan_read_mram(dev, config->mram_offsets[CAN_MCAN_MRAM_CFG_STD_FILTER] +
|
||||||
i * sizeof(struct can_mcan_std_filter), &filter,
|
i * sizeof(struct can_mcan_std_filter), &filter,
|
||||||
sizeof(struct can_mcan_std_filter));
|
sizeof(struct can_mcan_std_filter));
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
|
@ -958,12 +971,13 @@ static int can_mcan_get_free_std(const struct device *dev)
|
||||||
|
|
||||||
int can_mcan_get_max_filters(const struct device *dev, bool ide)
|
int can_mcan_get_max_filters(const struct device *dev, bool ide)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(dev);
|
const struct can_mcan_config *config = dev->config;
|
||||||
|
const struct can_mcan_callbacks *cbs = config->callbacks;
|
||||||
|
|
||||||
if (ide) {
|
if (ide) {
|
||||||
return NUM_EXT_FILTER_DATA;
|
return cbs->num_ext;
|
||||||
} else {
|
} else {
|
||||||
return NUM_STD_FILTER_DATA;
|
return cbs->num_std;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -975,6 +989,8 @@ int can_mcan_get_max_filters(const struct device *dev, bool ide)
|
||||||
int can_mcan_add_rx_filter_std(const struct device *dev, can_rx_callback_t callback,
|
int can_mcan_add_rx_filter_std(const struct device *dev, can_rx_callback_t callback,
|
||||||
void *user_data, const struct can_filter *filter)
|
void *user_data, const struct can_filter *filter)
|
||||||
{
|
{
|
||||||
|
const struct can_mcan_config *config = dev->config;
|
||||||
|
const struct can_mcan_callbacks *cbs = config->callbacks;
|
||||||
struct can_mcan_data *data = dev->data;
|
struct can_mcan_data *data = dev->data;
|
||||||
struct can_mcan_std_filter filter_element = {
|
struct can_mcan_std_filter filter_element = {
|
||||||
.id1 = filter->id,
|
.id1 = filter->id,
|
||||||
|
@ -996,7 +1012,7 @@ int can_mcan_add_rx_filter_std(const struct device *dev, can_rx_callback_t callb
|
||||||
/* TODO proper fifo balancing */
|
/* TODO proper fifo balancing */
|
||||||
filter_element.sfce = filter_id & 0x01 ? CAN_MCAN_FCE_FIFO1 : CAN_MCAN_FCE_FIFO0;
|
filter_element.sfce = filter_id & 0x01 ? CAN_MCAN_FCE_FIFO1 : CAN_MCAN_FCE_FIFO0;
|
||||||
|
|
||||||
err = can_mcan_write_mram(dev, CAN_MCAN_MRAM_OFFSET_STD_FILTER +
|
err = can_mcan_write_mram(dev, config->mram_offsets[CAN_MCAN_MRAM_CFG_STD_FILTER] +
|
||||||
filter_id * sizeof(struct can_mcan_std_filter),
|
filter_id * sizeof(struct can_mcan_std_filter),
|
||||||
&filter_element, sizeof(filter_element));
|
&filter_element, sizeof(filter_element));
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
|
@ -1008,39 +1024,24 @@ int can_mcan_add_rx_filter_std(const struct device *dev, can_rx_callback_t callb
|
||||||
|
|
||||||
LOG_DBG("Attached std filter at %d", filter_id);
|
LOG_DBG("Attached std filter at %d", filter_id);
|
||||||
|
|
||||||
if ((filter->flags & CAN_FILTER_RTR) != 0U) {
|
__ASSERT_NO_MSG(filter_id <= cbs->num_std);
|
||||||
data->std_filt_rtr |= (1U << filter_id);
|
cbs->std[filter_id].function = callback;
|
||||||
} else {
|
cbs->std[filter_id].user_data = user_data;
|
||||||
data->std_filt_rtr &= ~(1U << filter_id);
|
cbs->std[filter_id].flags = filter->flags;
|
||||||
}
|
|
||||||
|
|
||||||
if ((filter->flags & (CAN_FILTER_DATA | CAN_FILTER_RTR)) !=
|
|
||||||
(CAN_FILTER_DATA | CAN_FILTER_RTR)) {
|
|
||||||
data->std_filt_rtr_mask |= (1U << filter_id);
|
|
||||||
} else {
|
|
||||||
data->std_filt_rtr_mask &= ~(1U << filter_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((filter->flags & CAN_FILTER_FDF) != 0U) {
|
|
||||||
data->std_filt_fd_frame |= (1U << filter_id);
|
|
||||||
} else {
|
|
||||||
data->std_filt_fd_frame &= ~(1U << filter_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
data->rx_cb_std[filter_id] = callback;
|
|
||||||
data->cb_arg_std[filter_id] = user_data;
|
|
||||||
|
|
||||||
return filter_id;
|
return filter_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int can_mcan_get_free_ext(const struct device *dev)
|
static int can_mcan_get_free_ext(const struct device *dev)
|
||||||
{
|
{
|
||||||
|
const struct can_mcan_config *config = dev->config;
|
||||||
|
const struct can_mcan_callbacks *cbs = config->callbacks;
|
||||||
struct can_mcan_ext_filter filter;
|
struct can_mcan_ext_filter filter;
|
||||||
int err;
|
int err;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < NUM_EXT_FILTER_DATA; ++i) {
|
for (i = 0; i < cbs->num_ext; ++i) {
|
||||||
err = can_mcan_read_mram(dev, CAN_MCAN_MRAM_OFFSET_EXT_FILTER +
|
err = can_mcan_read_mram(dev, config->mram_offsets[CAN_MCAN_MRAM_CFG_EXT_FILTER] +
|
||||||
i * sizeof(struct can_mcan_ext_filter), &filter,
|
i * sizeof(struct can_mcan_ext_filter), &filter,
|
||||||
sizeof(struct can_mcan_ext_filter));
|
sizeof(struct can_mcan_ext_filter));
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
|
@ -1059,6 +1060,8 @@ static int can_mcan_get_free_ext(const struct device *dev)
|
||||||
static int can_mcan_add_rx_filter_ext(const struct device *dev, can_rx_callback_t callback,
|
static int can_mcan_add_rx_filter_ext(const struct device *dev, can_rx_callback_t callback,
|
||||||
void *user_data, const struct can_filter *filter)
|
void *user_data, const struct can_filter *filter)
|
||||||
{
|
{
|
||||||
|
const struct can_mcan_config *config = dev->config;
|
||||||
|
const struct can_mcan_callbacks *cbs = config->callbacks;
|
||||||
struct can_mcan_data *data = dev->data;
|
struct can_mcan_data *data = dev->data;
|
||||||
struct can_mcan_ext_filter filter_element = {
|
struct can_mcan_ext_filter filter_element = {
|
||||||
.id2 = filter->mask,
|
.id2 = filter->mask,
|
||||||
|
@ -1080,7 +1083,7 @@ static int can_mcan_add_rx_filter_ext(const struct device *dev, can_rx_callback_
|
||||||
/* TODO proper fifo balancing */
|
/* TODO proper fifo balancing */
|
||||||
filter_element.efce = filter_id & 0x01 ? CAN_MCAN_FCE_FIFO1 : CAN_MCAN_FCE_FIFO0;
|
filter_element.efce = filter_id & 0x01 ? CAN_MCAN_FCE_FIFO1 : CAN_MCAN_FCE_FIFO0;
|
||||||
|
|
||||||
err = can_mcan_write_mram(dev, CAN_MCAN_MRAM_OFFSET_EXT_FILTER +
|
err = can_mcan_write_mram(dev, config->mram_offsets[CAN_MCAN_MRAM_CFG_EXT_FILTER] +
|
||||||
filter_id * sizeof(struct can_mcan_ext_filter),
|
filter_id * sizeof(struct can_mcan_ext_filter),
|
||||||
&filter_element, sizeof(filter_element));
|
&filter_element, sizeof(filter_element));
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
|
@ -1092,27 +1095,10 @@ static int can_mcan_add_rx_filter_ext(const struct device *dev, can_rx_callback_
|
||||||
|
|
||||||
LOG_DBG("Attached ext filter at %d", filter_id);
|
LOG_DBG("Attached ext filter at %d", filter_id);
|
||||||
|
|
||||||
if ((filter->flags & CAN_FILTER_RTR) != 0U) {
|
__ASSERT_NO_MSG(filter_id <= cbs->num_ext);
|
||||||
data->ext_filt_rtr |= (1U << filter_id);
|
cbs->ext[filter_id].function = callback;
|
||||||
} else {
|
cbs->ext[filter_id].user_data = user_data;
|
||||||
data->ext_filt_rtr &= ~(1U << filter_id);
|
cbs->ext[filter_id].flags = filter->flags;
|
||||||
}
|
|
||||||
|
|
||||||
if ((filter->flags & (CAN_FILTER_DATA | CAN_FILTER_RTR)) !=
|
|
||||||
(CAN_FILTER_DATA | CAN_FILTER_RTR)) {
|
|
||||||
data->ext_filt_rtr_mask |= (1U << filter_id);
|
|
||||||
} else {
|
|
||||||
data->ext_filt_rtr_mask &= ~(1U << filter_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((filter->flags & CAN_FILTER_FDF) != 0U) {
|
|
||||||
data->ext_filt_fd_frame |= (1U << filter_id);
|
|
||||||
} else {
|
|
||||||
data->ext_filt_fd_frame &= ~(1U << filter_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
data->rx_cb_ext[filter_id] = callback;
|
|
||||||
data->cb_arg_ext[filter_id] = user_data;
|
|
||||||
|
|
||||||
return filter_id;
|
return filter_id;
|
||||||
}
|
}
|
||||||
|
@ -1120,6 +1106,8 @@ static int can_mcan_add_rx_filter_ext(const struct device *dev, can_rx_callback_
|
||||||
int can_mcan_add_rx_filter(const struct device *dev, can_rx_callback_t callback, void *user_data,
|
int can_mcan_add_rx_filter(const struct device *dev, can_rx_callback_t callback, void *user_data,
|
||||||
const struct can_filter *filter)
|
const struct can_filter *filter)
|
||||||
{
|
{
|
||||||
|
const struct can_mcan_config *config = dev->config;
|
||||||
|
const struct can_mcan_callbacks *cbs = config->callbacks;
|
||||||
int filter_id;
|
int filter_id;
|
||||||
|
|
||||||
if (callback == NULL) {
|
if (callback == NULL) {
|
||||||
|
@ -1139,7 +1127,7 @@ int can_mcan_add_rx_filter(const struct device *dev, can_rx_callback_t callback,
|
||||||
if ((filter->flags & CAN_FILTER_IDE) != 0U) {
|
if ((filter->flags & CAN_FILTER_IDE) != 0U) {
|
||||||
filter_id = can_mcan_add_rx_filter_ext(dev, callback, user_data, filter);
|
filter_id = can_mcan_add_rx_filter_ext(dev, callback, user_data, filter);
|
||||||
if (filter_id >= 0) {
|
if (filter_id >= 0) {
|
||||||
filter_id += NUM_STD_FILTER_DATA;
|
filter_id += cbs->num_std;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
filter_id = can_mcan_add_rx_filter_std(dev, callback, user_data, filter);
|
filter_id = can_mcan_add_rx_filter_std(dev, callback, user_data, filter);
|
||||||
|
@ -1150,27 +1138,29 @@ int can_mcan_add_rx_filter(const struct device *dev, can_rx_callback_t callback,
|
||||||
|
|
||||||
void can_mcan_remove_rx_filter(const struct device *dev, int filter_id)
|
void can_mcan_remove_rx_filter(const struct device *dev, int filter_id)
|
||||||
{
|
{
|
||||||
|
const struct can_mcan_config *config = dev->config;
|
||||||
|
const struct can_mcan_callbacks *cbs = config->callbacks;
|
||||||
struct can_mcan_data *data = dev->data;
|
struct can_mcan_data *data = dev->data;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
k_mutex_lock(&data->lock, K_FOREVER);
|
k_mutex_lock(&data->lock, K_FOREVER);
|
||||||
|
|
||||||
if (filter_id >= NUM_STD_FILTER_DATA) {
|
if (filter_id >= cbs->num_std) {
|
||||||
filter_id -= NUM_STD_FILTER_DATA;
|
filter_id -= cbs->num_std;
|
||||||
if (filter_id >= NUM_EXT_FILTER_DATA) {
|
if (filter_id >= cbs->num_ext) {
|
||||||
LOG_ERR("Wrong filter id");
|
LOG_ERR("Wrong filter id");
|
||||||
k_mutex_unlock(&data->lock);
|
k_mutex_unlock(&data->lock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = can_mcan_clear_mram(dev, CAN_MCAN_MRAM_OFFSET_EXT_FILTER +
|
err = can_mcan_clear_mram(dev, config->mram_offsets[CAN_MCAN_MRAM_CFG_EXT_FILTER] +
|
||||||
filter_id * sizeof(struct can_mcan_ext_filter),
|
filter_id * sizeof(struct can_mcan_ext_filter),
|
||||||
sizeof(struct can_mcan_ext_filter));
|
sizeof(struct can_mcan_ext_filter));
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
LOG_ERR("failed to clear ext filter element (err %d)", err);
|
LOG_ERR("failed to clear ext filter element (err %d)", err);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err = can_mcan_clear_mram(dev, CAN_MCAN_MRAM_OFFSET_STD_FILTER +
|
err = can_mcan_clear_mram(dev, config->mram_offsets[CAN_MCAN_MRAM_CFG_STD_FILTER] +
|
||||||
filter_id * sizeof(struct can_mcan_std_filter),
|
filter_id * sizeof(struct can_mcan_std_filter),
|
||||||
sizeof(struct can_mcan_std_filter));
|
sizeof(struct can_mcan_std_filter));
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
|
@ -1229,6 +1219,8 @@ unlock:
|
||||||
|
|
||||||
int can_mcan_configure_mram(const struct device *dev, uintptr_t mrba, uintptr_t mram)
|
int can_mcan_configure_mram(const struct device *dev, uintptr_t mrba, uintptr_t mram)
|
||||||
{
|
{
|
||||||
|
const struct can_mcan_config *config = dev->config;
|
||||||
|
uint32_t addr;
|
||||||
uint32_t reg;
|
uint32_t reg;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -1246,49 +1238,56 @@ int can_mcan_configure_mram(const struct device *dev, uintptr_t mrba, uintptr_t
|
||||||
|
|
||||||
can_mcan_enable_configuration_change(dev);
|
can_mcan_enable_configuration_change(dev);
|
||||||
|
|
||||||
reg = ((mram - mrba + CAN_MCAN_MRAM_OFFSET_STD_FILTER) & CAN_MCAN_SIDFC_FLSSA) |
|
addr = mram - mrba + config->mram_offsets[CAN_MCAN_MRAM_CFG_STD_FILTER];
|
||||||
FIELD_PREP(CAN_MCAN_SIDFC_LSS, NUM_STD_FILTER_ELEMENTS);
|
reg = (addr & CAN_MCAN_SIDFC_FLSSA) | FIELD_PREP(CAN_MCAN_SIDFC_LSS,
|
||||||
|
config->mram_elements[CAN_MCAN_MRAM_CFG_STD_FILTER]);
|
||||||
err = can_mcan_write_reg(dev, CAN_MCAN_SIDFC, reg);
|
err = can_mcan_write_reg(dev, CAN_MCAN_SIDFC, reg);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = ((mram - mrba + CAN_MCAN_MRAM_OFFSET_EXT_FILTER) & CAN_MCAN_XIDFC_FLESA) |
|
addr = mram - mrba + config->mram_offsets[CAN_MCAN_MRAM_CFG_EXT_FILTER];
|
||||||
FIELD_PREP(CAN_MCAN_XIDFC_LSS, NUM_EXT_FILTER_ELEMENTS);
|
reg = (addr & CAN_MCAN_XIDFC_FLESA) | FIELD_PREP(CAN_MCAN_XIDFC_LSS,
|
||||||
|
config->mram_elements[CAN_MCAN_MRAM_CFG_EXT_FILTER]);
|
||||||
err = can_mcan_write_reg(dev, CAN_MCAN_XIDFC, reg);
|
err = can_mcan_write_reg(dev, CAN_MCAN_XIDFC, reg);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = ((mram - mrba + CAN_MCAN_MRAM_OFFSET_RX_FIFO0) & CAN_MCAN_RXF0C_F0SA) |
|
addr = mram - mrba + config->mram_offsets[CAN_MCAN_MRAM_CFG_RX_FIFO0];
|
||||||
FIELD_PREP(CAN_MCAN_RXF0C_F0S, NUM_RX_FIFO0_ELEMENTS);
|
reg = (addr & CAN_MCAN_RXF0C_F0SA) | FIELD_PREP(CAN_MCAN_RXF0C_F0S,
|
||||||
|
config->mram_elements[CAN_MCAN_MRAM_CFG_RX_FIFO0]);
|
||||||
err = can_mcan_write_reg(dev, CAN_MCAN_RXF0C, reg);
|
err = can_mcan_write_reg(dev, CAN_MCAN_RXF0C, reg);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = ((mram - mrba + CAN_MCAN_MRAM_OFFSET_RX_FIFO1) & CAN_MCAN_RXF1C_F1SA) |
|
addr = mram - mrba + config->mram_offsets[CAN_MCAN_MRAM_CFG_RX_FIFO1];
|
||||||
FIELD_PREP(CAN_MCAN_RXF1C_F1S, NUM_RX_FIFO1_ELEMENTS);
|
reg = (addr & CAN_MCAN_RXF1C_F1SA) | FIELD_PREP(CAN_MCAN_RXF1C_F1S,
|
||||||
|
config->mram_elements[CAN_MCAN_MRAM_CFG_RX_FIFO1]);
|
||||||
err = can_mcan_write_reg(dev, CAN_MCAN_RXF1C, reg);
|
err = can_mcan_write_reg(dev, CAN_MCAN_RXF1C, reg);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = ((mram - mrba + CAN_MCAN_MRAM_OFFSET_RX_BUFFER) & CAN_MCAN_RXBC_RBSA);
|
addr = mram - mrba + config->mram_offsets[CAN_MCAN_MRAM_CFG_RX_BUFFER];
|
||||||
|
reg = (addr & CAN_MCAN_RXBC_RBSA);
|
||||||
err = can_mcan_write_reg(dev, CAN_MCAN_RXBC, reg);
|
err = can_mcan_write_reg(dev, CAN_MCAN_RXBC, reg);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = ((mram - mrba + CAN_MCAN_MRAM_OFFSET_TX_EVENT_FIFO) & CAN_MCAN_TXEFC_EFSA) |
|
addr = mram - mrba + config->mram_offsets[CAN_MCAN_MRAM_CFG_TX_EVENT_FIFO];
|
||||||
FIELD_PREP(CAN_MCAN_TXEFC_EFS, NUM_TX_EVENT_FIFO_ELEMENTS);
|
reg = (addr & CAN_MCAN_TXEFC_EFSA) | FIELD_PREP(CAN_MCAN_TXEFC_EFS,
|
||||||
|
config->mram_elements[CAN_MCAN_MRAM_CFG_TX_EVENT_FIFO]);
|
||||||
err = can_mcan_write_reg(dev, CAN_MCAN_TXEFC, reg);
|
err = can_mcan_write_reg(dev, CAN_MCAN_TXEFC, reg);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = ((mram - mrba + CAN_MCAN_MRAM_OFFSET_TX_BUFFER) & CAN_MCAN_TXBC_TBSA) |
|
addr = mram - mrba + config->mram_offsets[CAN_MCAN_MRAM_CFG_TX_BUFFER];
|
||||||
FIELD_PREP(CAN_MCAN_TXBC_TFQS, NUM_TX_BUF_ELEMENTS) | CAN_MCAN_TXBC_TFQM;
|
reg = (addr & CAN_MCAN_TXBC_TBSA) | FIELD_PREP(CAN_MCAN_TXBC_TFQS,
|
||||||
|
config->mram_elements[CAN_MCAN_MRAM_CFG_TX_BUFFER]) | CAN_MCAN_TXBC_TFQM;
|
||||||
err = can_mcan_write_reg(dev, CAN_MCAN_TXBC, reg);
|
err = can_mcan_write_reg(dev, CAN_MCAN_TXBC, reg);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
return err;
|
return err;
|
||||||
|
@ -1314,6 +1313,7 @@ int can_mcan_configure_mram(const struct device *dev, uintptr_t mrba, uintptr_t
|
||||||
int can_mcan_init(const struct device *dev)
|
int can_mcan_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct can_mcan_config *config = dev->config;
|
const struct can_mcan_config *config = dev->config;
|
||||||
|
const struct can_mcan_callbacks *cbs = config->callbacks;
|
||||||
struct can_mcan_data *data = dev->data;
|
struct can_mcan_data *data = dev->data;
|
||||||
struct can_timing timing;
|
struct can_timing timing;
|
||||||
#ifdef CONFIG_CAN_FD_MODE
|
#ifdef CONFIG_CAN_FD_MODE
|
||||||
|
@ -1327,10 +1327,15 @@ int can_mcan_init(const struct device *dev)
|
||||||
__ASSERT_NO_MSG(config->ops->read_mram != NULL);
|
__ASSERT_NO_MSG(config->ops->read_mram != NULL);
|
||||||
__ASSERT_NO_MSG(config->ops->write_mram != NULL);
|
__ASSERT_NO_MSG(config->ops->write_mram != NULL);
|
||||||
__ASSERT_NO_MSG(config->ops->clear_mram != NULL);
|
__ASSERT_NO_MSG(config->ops->clear_mram != NULL);
|
||||||
|
__ASSERT_NO_MSG(config->callbacks != NULL);
|
||||||
|
|
||||||
|
__ASSERT_NO_MSG(cbs->num_tx <= config->mram_elements[CAN_MCAN_MRAM_CFG_TX_BUFFER]);
|
||||||
|
__ASSERT_NO_MSG(cbs->num_std <= config->mram_elements[CAN_MCAN_MRAM_CFG_STD_FILTER]);
|
||||||
|
__ASSERT_NO_MSG(cbs->num_ext <= config->mram_elements[CAN_MCAN_MRAM_CFG_EXT_FILTER]);
|
||||||
|
|
||||||
k_mutex_init(&data->lock);
|
k_mutex_init(&data->lock);
|
||||||
k_mutex_init(&data->tx_mtx);
|
k_mutex_init(&data->tx_mtx);
|
||||||
k_sem_init(&data->tx_sem, NUM_TX_BUF_ELEMENTS, NUM_TX_BUF_ELEMENTS);
|
k_sem_init(&data->tx_sem, cbs->num_tx, cbs->num_tx);
|
||||||
|
|
||||||
if (config->phy != NULL) {
|
if (config->phy != NULL) {
|
||||||
if (!device_is_ready(config->phy)) {
|
if (!device_is_ready(config->phy)) {
|
||||||
|
@ -1503,5 +1508,5 @@ int can_mcan_init(const struct device *dev)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
return can_mcan_clear_mram(dev, 0, sizeof(struct can_mcan_msg_sram));
|
return can_mcan_clear_mram(dev, 0, config->mram_size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -384,27 +384,34 @@
|
||||||
#define CAN_MCAN_TXEFA 0x0F8
|
#define CAN_MCAN_TXEFA 0x0F8
|
||||||
#define CAN_MCAN_TXEFA_EFAI GENMASK(4, 0)
|
#define CAN_MCAN_TXEFA_EFAI GENMASK(4, 0)
|
||||||
|
|
||||||
#ifdef CONFIG_CAN_MCUX_MCAN
|
|
||||||
#define MCAN_DT_PATH DT_NODELABEL(can0)
|
|
||||||
#else
|
|
||||||
#define MCAN_DT_PATH DT_PATH(soc, can)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Indexes for the cells in the devicetree bosch,mram-cfg property. These match the
|
* @name Indexes for the cells in the devicetree bosch,mram-cfg property
|
||||||
* description of the cells in the bosch,m_can-base devicetree binding.
|
* @anchor CAN_MCAN_MRAM_CFG
|
||||||
|
|
||||||
|
* These match the description of the cells in the bosch,m_can-base devicetree binding.
|
||||||
|
*
|
||||||
|
* @{
|
||||||
*/
|
*/
|
||||||
enum can_mcan_mram_cfg {
|
/** offset cell index */
|
||||||
CAN_MCAN_MRAM_CFG_OFFSET = 0,
|
#define CAN_MCAN_MRAM_CFG_OFFSET 0
|
||||||
CAN_MCAN_MRAM_CFG_STD_FILTER,
|
/** std-filter-elements cell index */
|
||||||
CAN_MCAN_MRAM_CFG_EXT_FILTER,
|
#define CAN_MCAN_MRAM_CFG_STD_FILTER 1
|
||||||
CAN_MCAN_MRAM_CFG_RX_FIFO0,
|
/** ext-filter-elements cell index */
|
||||||
CAN_MCAN_MRAM_CFG_RX_FIFO1,
|
#define CAN_MCAN_MRAM_CFG_EXT_FILTER 2
|
||||||
CAN_MCAN_MRAM_CFG_RX_BUFFER,
|
/** rx-fifo0-elements cell index */
|
||||||
CAN_MCAN_MRAM_CFG_TX_EVENT,
|
#define CAN_MCAN_MRAM_CFG_RX_FIFO0 3
|
||||||
CAN_MCAN_MRAM_CFG_TX_BUFFER,
|
/** rx-fifo1-elements cell index */
|
||||||
CAN_MCAN_MRAM_CFG_NUM_CELLS
|
#define CAN_MCAN_MRAM_CFG_RX_FIFO1 4
|
||||||
};
|
/** rx-buffer-elements cell index */
|
||||||
|
#define CAN_MCAN_MRAM_CFG_RX_BUFFER 5
|
||||||
|
/** tx-event-fifo-elements cell index */
|
||||||
|
#define CAN_MCAN_MRAM_CFG_TX_EVENT_FIFO 6
|
||||||
|
/** tx-buffer-elements cell index */
|
||||||
|
#define CAN_MCAN_MRAM_CFG_TX_BUFFER 7
|
||||||
|
/** Total number of cells in bosch,mram-cfg property */
|
||||||
|
#define CAN_MCAN_MRAM_CFG_NUM_CELLS 8
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the Bosch M_CAN Message RAM offset
|
* @brief Get the Bosch M_CAN Message RAM offset
|
||||||
|
@ -413,7 +420,7 @@ enum can_mcan_mram_cfg {
|
||||||
* @return the Message RAM offset in bytes
|
* @return the Message RAM offset in bytes
|
||||||
*/
|
*/
|
||||||
#define CAN_MCAN_DT_MRAM_OFFSET(node_id) \
|
#define CAN_MCAN_DT_MRAM_OFFSET(node_id) \
|
||||||
DT_PROP_BY_IDX(node_id, bosch_mram_cfg, 0)
|
DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_OFFSET)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the number of standard (11-bit) filter elements in Bosch M_CAN Message RAM
|
* @brief Get the number of standard (11-bit) filter elements in Bosch M_CAN Message RAM
|
||||||
|
@ -421,8 +428,8 @@ enum can_mcan_mram_cfg {
|
||||||
* @param node_id node identifier
|
* @param node_id node identifier
|
||||||
* @return the number of standard (11-bit) filter elements
|
* @return the number of standard (11-bit) filter elements
|
||||||
*/
|
*/
|
||||||
#define CAN_MCAN_DT_MRAM_STD_FILTER_ELEM(node_id) \
|
#define CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(node_id) \
|
||||||
DT_PROP_BY_IDX(node_id, bosch_mram_cfg, 1)
|
DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_STD_FILTER)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the number of extended (29-bit) filter elements in Bosch M_CAN Message RAM
|
* @brief Get the number of extended (29-bit) filter elements in Bosch M_CAN Message RAM
|
||||||
|
@ -430,8 +437,8 @@ enum can_mcan_mram_cfg {
|
||||||
* @param node_id node identifier
|
* @param node_id node identifier
|
||||||
* @return the number of extended (29-bit) filter elements
|
* @return the number of extended (29-bit) filter elements
|
||||||
*/
|
*/
|
||||||
#define CAN_MCAN_DT_MRAM_EXT_FILTER_ELEM(node_id) \
|
#define CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(node_id) \
|
||||||
DT_PROP_BY_IDX(node_id, bosch_mram_cfg, 2)
|
DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_EXT_FILTER)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the number of Rx FIFO 0 elements in Bosch M_CAN Message RAM
|
* @brief Get the number of Rx FIFO 0 elements in Bosch M_CAN Message RAM
|
||||||
|
@ -439,8 +446,8 @@ enum can_mcan_mram_cfg {
|
||||||
* @param node_id node identifier
|
* @param node_id node identifier
|
||||||
* @return the number of Rx FIFO 0 elements
|
* @return the number of Rx FIFO 0 elements
|
||||||
*/
|
*/
|
||||||
#define CAN_MCAN_DT_MRAM_RX_FIFO0_ELEM(node_id) \
|
#define CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS(node_id) \
|
||||||
DT_PROP_BY_IDX(node_id, bosch_mram_cfg, 3)
|
DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_RX_FIFO0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the number of Rx FIFO 1 elements in Bosch M_CAN Message RAM
|
* @brief Get the number of Rx FIFO 1 elements in Bosch M_CAN Message RAM
|
||||||
|
@ -448,8 +455,8 @@ enum can_mcan_mram_cfg {
|
||||||
* @param node_id node identifier
|
* @param node_id node identifier
|
||||||
* @return the number of Rx FIFO 1 elements
|
* @return the number of Rx FIFO 1 elements
|
||||||
*/
|
*/
|
||||||
#define CAN_MCAN_DT_MRAM_RX_FIFO1_ELEM(node_id) \
|
#define CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS(node_id) \
|
||||||
DT_PROP_BY_IDX(node_id, bosch_mram_cfg, 4)
|
DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_RX_FIFO1)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the number of Rx Buffer elements in Bosch M_CAN Message RAM
|
* @brief Get the number of Rx Buffer elements in Bosch M_CAN Message RAM
|
||||||
|
@ -457,8 +464,8 @@ enum can_mcan_mram_cfg {
|
||||||
* @param node_id node identifier
|
* @param node_id node identifier
|
||||||
* @return the number of Rx Buffer elements
|
* @return the number of Rx Buffer elements
|
||||||
*/
|
*/
|
||||||
#define CAN_MCAN_DT_MRAM_RX_BUFFER_ELEM(node_id) \
|
#define CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS(node_id) \
|
||||||
DT_PROP_BY_IDX(node_id, bosch_mram_cfg, 5)
|
DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_RX_BUFFER)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the number of Tx Event FIFO elements in Bosch M_CAN Message RAM
|
* @brief Get the number of Tx Event FIFO elements in Bosch M_CAN Message RAM
|
||||||
|
@ -466,8 +473,8 @@ enum can_mcan_mram_cfg {
|
||||||
* @param node_id node identifier
|
* @param node_id node identifier
|
||||||
* @return the number of Tx Event FIFO elements
|
* @return the number of Tx Event FIFO elements
|
||||||
*/
|
*/
|
||||||
#define CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEM(node_id) \
|
#define CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS(node_id) \
|
||||||
DT_PROP_BY_IDX(node_id, bosch_mram_cfg, 6)
|
DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_TX_EVENT_FIFO)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the number of Tx Buffer elements in Bosch M_CAN Message RAM
|
* @brief Get the number of Tx Buffer elements in Bosch M_CAN Message RAM
|
||||||
|
@ -475,8 +482,163 @@ enum can_mcan_mram_cfg {
|
||||||
* @param node_id node identifier
|
* @param node_id node identifier
|
||||||
* @return the number of Tx Buffer elements
|
* @return the number of Tx Buffer elements
|
||||||
*/
|
*/
|
||||||
#define CAN_MCAN_DT_MRAM_TX_BUFFER_ELEM(node_id) \
|
#define CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(node_id) \
|
||||||
DT_PROP_BY_IDX(node_id, bosch_mram_cfg, 7)
|
DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_TX_BUFFER)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the base offset of standard (11-bit) filter elements in Bosch M_CAN Message RAM
|
||||||
|
*
|
||||||
|
* @param node_id node identifier
|
||||||
|
* @return the base offset of standard (11-bit) filter elements in bytes
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_MRAM_STD_FILTER_OFFSET(node_id) (0U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the base offset of extended (29-bit) filter elements in Bosch M_CAN Message RAM
|
||||||
|
*
|
||||||
|
* @param node_id node identifier
|
||||||
|
* @return the base offset of extended (29-bit) filter elements in bytes
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_MRAM_EXT_FILTER_OFFSET(node_id) \
|
||||||
|
(CAN_MCAN_DT_MRAM_STD_FILTER_OFFSET(node_id) + \
|
||||||
|
CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(node_id) * sizeof(struct can_mcan_std_filter))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the base offset of Rx FIFO 0 elements in Bosch M_CAN Message RAM
|
||||||
|
*
|
||||||
|
* @param node_id node identifier
|
||||||
|
* @return the base offset of Rx FIFO 0 elements in bytes
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_MRAM_RX_FIFO0_OFFSET(node_id) \
|
||||||
|
(CAN_MCAN_DT_MRAM_EXT_FILTER_OFFSET(node_id) + \
|
||||||
|
CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(node_id) * sizeof(struct can_mcan_ext_filter))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the base offset of Rx FIFO 1 elements in Bosch M_CAN Message RAM
|
||||||
|
*
|
||||||
|
* @param node_id node identifier
|
||||||
|
* @return the base offset of Rx FIFO 1 elements in bytes
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_MRAM_RX_FIFO1_OFFSET(node_id) \
|
||||||
|
(CAN_MCAN_DT_MRAM_RX_FIFO0_OFFSET(node_id) + \
|
||||||
|
CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS(node_id) * sizeof(struct can_mcan_rx_fifo))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the base offset of Rx Buffer elements in Bosch M_CAN Message RAM
|
||||||
|
*
|
||||||
|
* @param node_id node identifier
|
||||||
|
* @return the base offset of Rx Buffer elements in bytes
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_MRAM_RX_BUFFER_OFFSET(node_id) \
|
||||||
|
(CAN_MCAN_DT_MRAM_RX_FIFO1_OFFSET(node_id) + \
|
||||||
|
CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS(node_id) * sizeof(struct can_mcan_rx_fifo))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the base offset of Tx Event FIFO elements in Bosch M_CAN Message RAM
|
||||||
|
*
|
||||||
|
* @param node_id node identifier
|
||||||
|
* @return the base offset of Tx Event FIFO elements in bytes
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_OFFSET(node_id) \
|
||||||
|
(CAN_MCAN_DT_MRAM_RX_BUFFER_OFFSET(node_id) + \
|
||||||
|
CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS(node_id) * sizeof(struct can_mcan_rx_fifo))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the base offset of Tx Buffer elements in Bosch M_CAN Message RAM
|
||||||
|
*
|
||||||
|
* @param node_id node identifier
|
||||||
|
* @return the base offset of Tx Buffer elements in bytes
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_MRAM_TX_BUFFER_OFFSET(node_id) \
|
||||||
|
(CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_OFFSET(node_id) + \
|
||||||
|
CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS(node_id) * sizeof(struct can_mcan_tx_event_fifo))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the Bosch M_CAN register base address
|
||||||
|
*
|
||||||
|
* For devicetree nodes with just one register block, this macro returns the base address of that
|
||||||
|
* register block.
|
||||||
|
*
|
||||||
|
* If a devicetree node has more than one register block, this macros returns the base address of
|
||||||
|
* the register block named "m_can".
|
||||||
|
*
|
||||||
|
* @param node_id node identifier
|
||||||
|
* @return the Bosch M_CAN register base address
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_MCAN_ADDR(node_id) \
|
||||||
|
COND_CODE_1(DT_NUM_REGS(node_id), ((mm_reg_t)DT_REG_ADDR(node_id)), \
|
||||||
|
((mm_reg_t)DT_REG_ADDR_BY_NAME(node_id, m_can)))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the Bosch M_CAN Message RAM base address
|
||||||
|
*
|
||||||
|
* For devicetree nodes with dedicated Message RAM area defined via devicetree, this macro returns
|
||||||
|
* the base address of the Message RAM, taking in the Message RAM offset into account.
|
||||||
|
*
|
||||||
|
* @param node_id node identifier
|
||||||
|
* @return the Bosch M_CAN Message RAM base address
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_MRAM_ADDR(node_id) \
|
||||||
|
(mem_addr_t)(DT_REG_ADDR_BY_NAME(node_id, message_ram) + CAN_MCAN_DT_MRAM_OFFSET(node_id))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the Bosch M_CAN Message RAM size
|
||||||
|
*
|
||||||
|
* For devicetree nodes with dedicated Message RAM area defined via devicetree, this macro returns
|
||||||
|
* the size of the Message RAM, taking in the Message RAM offset into account.
|
||||||
|
*
|
||||||
|
* @param node_id node identifier
|
||||||
|
* @return the Bosch M_CAN Message RAM base address
|
||||||
|
* @see CAN_MCAN_DT_MRAM_ELEMENTS_SIZE()
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_MRAM_SIZE(node_id) \
|
||||||
|
(mem_addr_t)(DT_REG_SIZE_BY_NAME(node_id, message_ram) - CAN_MCAN_DT_MRAM_OFFSET(node_id))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the total size of all Bosch M_CAN Message RAM elements
|
||||||
|
*
|
||||||
|
* @param node_id node identifier
|
||||||
|
* @return the total size of all Message RAM elements in bytes
|
||||||
|
* @see CAN_MCAN_DT_MRAM_SIZE()
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(node_id) \
|
||||||
|
(CAN_MCAN_DT_MRAM_TX_BUFFER_OFFSET(node_id) + \
|
||||||
|
CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(node_id) * sizeof(struct can_mcan_tx_buffer))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Define a RAM buffer for Bosch M_CAN Message RAM
|
||||||
|
*
|
||||||
|
* For devicetree nodes without dedicated Message RAM area, this macro defines a suitable RAM buffer
|
||||||
|
* to hold the Message RAM elements. Since this buffer cannot be shared between multiple Bosch M_CAN
|
||||||
|
* instances, the Message RAM offset must be set to 0x0.
|
||||||
|
*
|
||||||
|
* @param node_id node identifier
|
||||||
|
* @param _name buffer variable name
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_MRAM_DEFINE(node_id, _name) \
|
||||||
|
BUILD_ASSERT(CAN_MCAN_DT_MRAM_OFFSET(node_id) == 0, "offset must be 0"); \
|
||||||
|
static char __noinit __nocache __aligned(4) _name[CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(node_id)];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Assert that the Message RAM configuration meets the Bosch M_CAN IP core restrictions
|
||||||
|
*
|
||||||
|
* @param node_id node identifier
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_BUILD_ASSERT_MRAM_CFG(node_id) \
|
||||||
|
BUILD_ASSERT(CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(node_id) <= 128, \
|
||||||
|
"Maximum Standard filter elements exceeded"); \
|
||||||
|
BUILD_ASSERT(CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(node_id) <= 64, \
|
||||||
|
"Maximum Extended filter elements exceeded"); \
|
||||||
|
BUILD_ASSERT(CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS(node_id) <= 64, \
|
||||||
|
"Maximum Rx FIFO 0 elements exceeded"); \
|
||||||
|
BUILD_ASSERT(CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS(node_id) <= 64, \
|
||||||
|
"Maximum Rx FIFO 1 elements exceeded"); \
|
||||||
|
BUILD_ASSERT(CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS(node_id) <= 64, \
|
||||||
|
"Maximum Rx Buffer elements exceeded"); \
|
||||||
|
BUILD_ASSERT(CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS(node_id) <= 32, \
|
||||||
|
"Maximum Tx Buffer elements exceeded"); \
|
||||||
|
BUILD_ASSERT(CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(node_id) <= 32, \
|
||||||
|
"Maximum Tx Buffer elements exceeded");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Equivalent to CAN_MCAN_DT_MRAM_OFFSET(DT_DRV_INST(inst))
|
* @brief Equivalent to CAN_MCAN_DT_MRAM_OFFSET(DT_DRV_INST(inst))
|
||||||
|
@ -484,96 +646,181 @@ enum can_mcan_mram_cfg {
|
||||||
* @return the Message RAM offset in bytes
|
* @return the Message RAM offset in bytes
|
||||||
* @see CAN_MCAN_DT_MRAM_OFFSET()
|
* @see CAN_MCAN_DT_MRAM_OFFSET()
|
||||||
*/
|
*/
|
||||||
#define CAN_MCAN_DT_INST_MRAM_OFFSET(inst) \
|
#define CAN_MCAN_DT_INST_MRAM_OFFSET(inst) CAN_MCAN_DT_MRAM_OFFSET(DT_DRV_INST(inst))
|
||||||
CAN_MCAN_DT_MRAM_OFFSET(DT_DRV_INST(inst))
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Equivalent to CAN_MCAN_DT_MRAM_STD_FILTER_ELEM(DT_DRV_INST(inst))
|
* @brief Equivalent to CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(DT_DRV_INST(inst))
|
||||||
* @param inst DT_DRV_COMPAT instance number
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
* @return the number of standard (11-bit) elements
|
* @return the number of standard (11-bit) elements
|
||||||
* @see CAN_MCAN_DT_MRAM_STD_FILTER_ELEM()
|
* @see CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS()
|
||||||
*/
|
*/
|
||||||
#define CAN_MCAN_DT_INST_MRAM_STD_FILTER_ELEM(inst) \
|
#define CAN_MCAN_DT_INST_MRAM_STD_FILTER_ELEMENTS(inst) \
|
||||||
CAN_MCAN_DT_MRAM_STD_FILTER_ELEMDT_DRV_INST(inst))
|
CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(DT_DRV_INST(inst))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Equivalent to CAN_MCAN_DT_MRAM_EXT_FILTER_ELEM(DT_DRV_INST(inst))
|
* @brief Equivalent to CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(DT_DRV_INST(inst))
|
||||||
* @param inst DT_DRV_COMPAT instance number
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
* @return the number of extended (29-bit) elements
|
* @return the number of extended (29-bit) elements
|
||||||
* @see CAN_MCAN_DT_MRAM_EXT_FILTER_ELEM()
|
* @see CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS()
|
||||||
*/
|
*/
|
||||||
#define CAN_MCAN_DT_INST_MRAM_EXT_FILTER_ELEM(inst) \
|
#define CAN_MCAN_DT_INST_MRAM_EXT_FILTER_ELEMENTS(inst) \
|
||||||
CAN_MCAN_DT_MRAM_EXT_FILTER_ELEM(DT_DRV_INST(inst))
|
CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(DT_DRV_INST(inst))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Equivalent to CAN_MCAN_DT_MRAM_RX_FIFO0_ELEM(DT_DRV_INST(inst))
|
* @brief Equivalent to CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS(DT_DRV_INST(inst))
|
||||||
* @param inst DT_DRV_COMPAT instance number
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
* @return the number of Rx FIFO 0 elements
|
* @return the number of Rx FIFO 0 elements
|
||||||
* @see CAN_MCAN_DT_MRAM_RX_FIFO0_ELEM()
|
* @see CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS()
|
||||||
*/
|
*/
|
||||||
#define CAN_MCAN_DT_INST_MRAM_RX_FIFO0_ELEM(inst) \
|
#define CAN_MCAN_DT_INST_MRAM_RX_FIFO0_ELEMENTS(inst) \
|
||||||
CAN_MCAN_DT_MRAM_RX_FIFO0_ELEM(DT_DRV_INST(inst))
|
CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS(DT_DRV_INST(inst))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Equivalent to CAN_MCAN_DT_MRAM_RX_FIFO1_ELEM(DT_DRV_INST(inst))
|
* @brief Equivalent to CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS(DT_DRV_INST(inst))
|
||||||
* @param inst DT_DRV_COMPAT instance number
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
* @return the number of Rx FIFO 1 elements
|
* @return the number of Rx FIFO 1 elements
|
||||||
* @see CAN_MCAN_DT_MRAM_RX_FIFO1_ELEM()
|
* @see CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS()
|
||||||
*/
|
*/
|
||||||
#define CAN_MCAN_DT_INST_MRAM_RX_FIFO1_ELEM(inst) \
|
#define CAN_MCAN_DT_INST_MRAM_RX_FIFO1_ELEMENTS(inst) \
|
||||||
CAN_MCAN_DT_MRAM_RX_FIFO1_ELEM(DT_DRV_INST(inst))
|
CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS(DT_DRV_INST(inst))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Equivalent to CAN_MCAN_DT_MRAM_RX_BUFFER_ELEM(DT_DRV_INST(inst))
|
* @brief Equivalent to CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS(DT_DRV_INST(inst))
|
||||||
* @param inst DT_DRV_COMPAT instance number
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
* @return the number of Rx Buffer elements
|
* @return the number of Rx Buffer elements
|
||||||
* @see CAN_MCAN_DT_MRAM_RX_BUFFER_ELEM()
|
* @see CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS()
|
||||||
*/
|
*/
|
||||||
#define CAN_MCAN_DT_INST_MRAM_RX_BUFFER_ELEM(inst) \
|
#define CAN_MCAN_DT_INST_MRAM_RX_BUFFER_ELEMENTS(inst) \
|
||||||
CAN_MCAN_DT_MRAM_RX_BUFFER_ELEM(DT_DRV_INST(inst))
|
CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS(DT_DRV_INST(inst))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Equivalent to CAN_MCAN_DT_MRAM_TX_EVENT_ELEM(DT_DRV_INST(inst))
|
* @brief Equivalent to CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS(DT_DRV_INST(inst))
|
||||||
* @param inst DT_DRV_COMPAT instance number
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
* @return the number of Tx Event FIFO elements
|
* @return the number of Tx Event FIFO elements
|
||||||
* @see CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEM()
|
* @see CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS()
|
||||||
*/
|
*/
|
||||||
#define CAN_MCAN_DT_INST_MRAM_TX_EVENT_FIFO_ELEM(inst) \
|
#define CAN_MCAN_DT_INST_MRAM_TX_EVENT_FIFO_ELEMENTS(inst) \
|
||||||
CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEM(DT_DRV_INST(inst))
|
CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS(DT_DRV_INST(inst))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Equivalent to CAN_MCAN_DT_MRAM_TX_BUFFER_ELEM(DT_DRV_INST(inst))
|
* @brief Equivalent to CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(DT_DRV_INST(inst))
|
||||||
* @param inst DT_DRV_COMPAT instance number
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
* @return the number of Tx Buffer elements
|
* @return the number of Tx Buffer elements
|
||||||
* @see CAN_MCAN_DT_MRAM_TX_BUFFER_ELEM()
|
* @see CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS()
|
||||||
*/
|
*/
|
||||||
#define CAN_MCAN_DT_INST_MRAM_TX_BUFFER_ELEM(inst) \
|
#define CAN_MCAN_DT_INST_MRAM_TX_BUFFER_ELEMENTS(inst) \
|
||||||
CAN_MCAN_DT_MRAM_TX_BUFFER_ELEM(DT_DRV_INST(inst))
|
CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(DT_DRV_INST(inst))
|
||||||
|
|
||||||
#define NUM_STD_FILTER_ELEMENTS CAN_MCAN_DT_MRAM_STD_FILTER_ELEM(MCAN_DT_PATH)
|
/**
|
||||||
#define NUM_EXT_FILTER_ELEMENTS CAN_MCAN_DT_MRAM_EXT_FILTER_ELEM(MCAN_DT_PATH)
|
* @brief Equivalent to CAN_MCAN_DT_MRAM_STD_FILTER_OFFSET(DT_DRV_INST(inst))
|
||||||
#define NUM_RX_FIFO0_ELEMENTS CAN_MCAN_DT_MRAM_RX_FIFO0_ELEM(MCAN_DT_PATH)
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
#define NUM_RX_FIFO1_ELEMENTS CAN_MCAN_DT_MRAM_RX_FIFO1_ELEM(MCAN_DT_PATH)
|
* @return the base offset of standard (11-bit) filter elements in bytes
|
||||||
#define NUM_RX_BUF_ELEMENTS CAN_MCAN_DT_MRAM_RX_BUFFER_ELEM(MCAN_DT_PATH)
|
* @see CAN_MCAN_DT_MRAM_STD_FILTER_OFFSET()
|
||||||
#define NUM_TX_EVENT_FIFO_ELEMENTS CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEM(MCAN_DT_PATH)
|
*/
|
||||||
#define NUM_TX_BUF_ELEMENTS CAN_MCAN_DT_MRAM_TX_BUFFER_ELEM(MCAN_DT_PATH)
|
#define CAN_MCAN_DT_INST_MRAM_STD_FILTER_OFFSET(inst) \
|
||||||
|
CAN_MCAN_DT_MRAM_STD_FILTER_OFFSET(DT_DRV_INST(inst))
|
||||||
|
|
||||||
/* Assert that the Message RAM configuration meets the M_CAN IP core restrictions */
|
/**
|
||||||
BUILD_ASSERT(NUM_STD_FILTER_ELEMENTS <= 128, "Maximum Standard filter elements exceeded");
|
* @brief Equivalent to CAN_MCAN_DT_MRAM_EXT_FILTER_OFFSET(DT_DRV_INST(inst))
|
||||||
BUILD_ASSERT(NUM_EXT_FILTER_ELEMENTS <= 64, "Maximum Extended filter elements exceeded");
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
BUILD_ASSERT(NUM_RX_FIFO0_ELEMENTS <= 64, "Maximum Rx FIFO 0 elements exceeded");
|
* @return the base offset of extended (29-bit) filter elements in bytes
|
||||||
BUILD_ASSERT(NUM_RX_FIFO1_ELEMENTS <= 64, "Maximum Rx FIFO 1 elements exceeded");
|
* @see CAN_MCAN_DT_MRAM_EXT_FILTER_OFFSET()
|
||||||
BUILD_ASSERT(NUM_RX_BUF_ELEMENTS <= 64, "Maximum Rx Buffer elements exceeded");
|
*/
|
||||||
BUILD_ASSERT(NUM_TX_EVENT_FIFO_ELEMENTS <= 32, "Maximum Tx Buffer elements exceeded");
|
#define CAN_MCAN_DT_INST_MRAM_EXT_FILTER_OFFSET(inst) \
|
||||||
BUILD_ASSERT(NUM_TX_BUF_ELEMENTS <= 32, "Maximum Tx Buffer elements exceeded");
|
CAN_MCAN_DT_MRAM_EXT_FILTER_OFFSET(DT_DRV_INST(inst))
|
||||||
|
|
||||||
#ifdef CONFIG_CAN_STM32FD
|
/**
|
||||||
#define NUM_STD_FILTER_DATA CONFIG_CAN_MAX_STD_ID_FILTER
|
* @brief Equivalent to CAN_MCAN_DT_MRAM_RX_FIFO0_OFFSET(DT_DRV_INST(inst))
|
||||||
#define NUM_EXT_FILTER_DATA CONFIG_CAN_MAX_EXT_ID_FILTER
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
#else
|
* @return the base offset of Rx FIFO 0 elements in bytes
|
||||||
#define NUM_STD_FILTER_DATA NUM_STD_FILTER_ELEMENTS
|
* @see CAN_MCAN_DT_MRAM_RX_FIFO0_OFFSET()
|
||||||
#define NUM_EXT_FILTER_DATA NUM_EXT_FILTER_ELEMENTS
|
*/
|
||||||
#endif
|
#define CAN_MCAN_DT_INST_MRAM_RX_FIFO0_OFFSET(inst) \
|
||||||
|
CAN_MCAN_DT_MRAM_RX_FIFO0_OFFSET(DT_DRV_INST(inst))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Equivalent to CAN_MCAN_DT_MRAM_RX_FIFO1_OFFSET(DT_DRV_INST(inst))
|
||||||
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
|
* @return the base offset of Rx FIFO 1 elements in bytes
|
||||||
|
* @see CAN_MCAN_DT_MRAM_RX_FIFO1_OFFSET()
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_INST_MRAM_RX_FIFO1_OFFSET(inst) \
|
||||||
|
CAN_MCAN_DT_MRAM_RX_FIFO1_OFFSET(DT_DRV_INST(inst))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Equivalent to CAN_MCAN_DT_MRAM_RX_BUFFER_OFFSET(DT_DRV_INST(inst))
|
||||||
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
|
* @return the base offset of Rx Buffer elements in bytes
|
||||||
|
* @see CAN_MCAN_DT_MRAM_RX_BUFFER_OFFSET()
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_INST_MRAM_RX_BUFFER_OFFSET(inst) \
|
||||||
|
CAN_MCAN_DT_MRAM_RX_BUFFER_OFFSET(DT_DRV_INST(inst))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Equivalent to CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_OFFSET(DT_DRV_INST(inst))
|
||||||
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
|
* @return the base offset of Tx Event FIFO elements in bytes
|
||||||
|
* @see CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_OFFSET()
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_INST_MRAM_TX_EVENT_FIFO_OFFSET(inst) \
|
||||||
|
CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_OFFSET(DT_DRV_INST(inst))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Equivalent to CAN_MCAN_DT_MRAM_TX_BUFFER_OFFSET(DT_DRV_INST(inst))
|
||||||
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
|
* @return the base offset of Tx Buffer elements in bytes
|
||||||
|
* @see CAN_MCAN_DT_MRAM_TX_BUFFER_OFFSET()
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_INST_MRAM_TX_BUFFER_OFFSET(inst) \
|
||||||
|
CAN_MCAN_DT_MRAM_TX_BUFFER_OFFSET(DT_DRV_INST(inst))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Equivalent to CAN_MCAN_DT_MCAN_ADDR(DT_DRV_INST(inst))
|
||||||
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
|
* @return the Bosch M_CAN register base address
|
||||||
|
* @see CAN_MCAN_DT_MRAM_ADDR()
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_INST_MCAN_ADDR(inst) CAN_MCAN_DT_MCAN_ADDR(DT_DRV_INST(inst))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Equivalent to CAN_MCAN_DT_MRAM_ADDR(DT_DRV_INST(inst))
|
||||||
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
|
* @return the Bosch M_CAN Message RAM base address
|
||||||
|
* @see CAN_MCAN_DT_MRAM_ADDR()
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_INST_MRAM_ADDR(inst) CAN_MCAN_DT_MRAM_ADDR(DT_DRV_INST(inst))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Equivalent to CAN_MCAN_DT_MRAM_SIZE(DT_DRV_INST(inst))
|
||||||
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
|
* @return the Bosch M_CAN Message RAM size in bytes
|
||||||
|
* @see CAN_MCAN_DT_MRAM_SIZE()
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_INST_MRAM_SIZE(inst) CAN_MCAN_DT_MRAM_SIZE(DT_DRV_INST(inst))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Equivalent to CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(DT_DRV_INST(inst))
|
||||||
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
|
* @return the total size of all Message RAM elements in bytes
|
||||||
|
* @see CAN_MCAN_DT_MRAM_ELEMENTS_SIZE()
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_INST_MRAM_ELEMENTS_SIZE(inst) CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(DT_DRV_INST(inst))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Equivalent to CAN_MCAN_DT_MRAM_DEFINE(DT_DRV_INST(inst))
|
||||||
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
|
* @param _name buffer variable name
|
||||||
|
* @see CAN_MCAN_DT_MRAM_DEFINE()
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_INST_MRAM_DEFINE(inst, _name) CAN_MCAN_DT_MRAM_DEFINE(DT_DRV_INST(inst), _name)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Equivalent to CAN_MCAN_DT_BUILD_ASSERT_MRAM_CFG(DT_DRV_INST(inst))
|
||||||
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
|
* @see CAN_MCAN_DT_BUILD_ASSERT_MRAM_CFG()
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_INST_BUILD_ASSERT_MRAM_CFG(inst) \
|
||||||
|
CAN_MCAN_DT_BUILD_ASSERT_MRAM_CFG(DT_DRV_INST(inst))
|
||||||
|
|
||||||
struct can_mcan_rx_fifo_hdr {
|
struct can_mcan_rx_fifo_hdr {
|
||||||
union {
|
union {
|
||||||
|
@ -689,42 +936,12 @@ struct can_mcan_ext_filter {
|
||||||
uint32_t eft: 2; /* Filter type */
|
uint32_t eft: 2; /* Filter type */
|
||||||
} __packed __aligned(4);
|
} __packed __aligned(4);
|
||||||
|
|
||||||
struct can_mcan_msg_sram {
|
|
||||||
struct can_mcan_std_filter std_filt[NUM_STD_FILTER_ELEMENTS];
|
|
||||||
struct can_mcan_ext_filter ext_filt[NUM_EXT_FILTER_ELEMENTS];
|
|
||||||
struct can_mcan_rx_fifo rx_fifo0[NUM_RX_FIFO0_ELEMENTS];
|
|
||||||
struct can_mcan_rx_fifo rx_fifo1[NUM_RX_FIFO1_ELEMENTS];
|
|
||||||
struct can_mcan_rx_fifo rx_buffer[NUM_RX_BUF_ELEMENTS];
|
|
||||||
struct can_mcan_tx_event_fifo tx_event_fifo[NUM_TX_EVENT_FIFO_ELEMENTS];
|
|
||||||
struct can_mcan_tx_buffer tx_buffer[NUM_TX_BUF_ELEMENTS];
|
|
||||||
} __packed __aligned(4);
|
|
||||||
|
|
||||||
#define CAN_MCAN_MRAM_OFFSET_STD_FILTER offsetof(struct can_mcan_msg_sram, std_filt)
|
|
||||||
#define CAN_MCAN_MRAM_OFFSET_EXT_FILTER offsetof(struct can_mcan_msg_sram, ext_filt)
|
|
||||||
#define CAN_MCAN_MRAM_OFFSET_RX_FIFO0 offsetof(struct can_mcan_msg_sram, rx_fifo0)
|
|
||||||
#define CAN_MCAN_MRAM_OFFSET_RX_FIFO1 offsetof(struct can_mcan_msg_sram, rx_fifo1)
|
|
||||||
#define CAN_MCAN_MRAM_OFFSET_RX_BUFFER offsetof(struct can_mcan_msg_sram, rx_buffer)
|
|
||||||
#define CAN_MCAN_MRAM_OFFSET_TX_EVENT_FIFO offsetof(struct can_mcan_msg_sram, tx_event_fifo)
|
|
||||||
#define CAN_MCAN_MRAM_OFFSET_TX_BUFFER offsetof(struct can_mcan_msg_sram, tx_buffer)
|
|
||||||
|
|
||||||
struct can_mcan_data {
|
struct can_mcan_data {
|
||||||
struct k_mutex lock;
|
struct k_mutex lock;
|
||||||
struct k_sem tx_sem;
|
struct k_sem tx_sem;
|
||||||
struct k_mutex tx_mtx;
|
struct k_mutex tx_mtx;
|
||||||
can_tx_callback_t tx_fin_cb[NUM_TX_BUF_ELEMENTS];
|
|
||||||
void *tx_fin_cb_arg[NUM_TX_BUF_ELEMENTS];
|
|
||||||
can_rx_callback_t rx_cb_std[NUM_STD_FILTER_DATA];
|
|
||||||
can_rx_callback_t rx_cb_ext[NUM_EXT_FILTER_DATA];
|
|
||||||
void *cb_arg_std[NUM_STD_FILTER_DATA];
|
|
||||||
void *cb_arg_ext[NUM_EXT_FILTER_DATA];
|
|
||||||
can_state_change_callback_t state_change_cb;
|
can_state_change_callback_t state_change_cb;
|
||||||
void *state_change_cb_data;
|
void *state_change_cb_data;
|
||||||
uint32_t std_filt_fd_frame;
|
|
||||||
uint32_t std_filt_rtr;
|
|
||||||
uint32_t std_filt_rtr_mask;
|
|
||||||
uint16_t ext_filt_fd_frame;
|
|
||||||
uint16_t ext_filt_rtr;
|
|
||||||
uint16_t ext_filt_rtr_mask;
|
|
||||||
bool started;
|
bool started;
|
||||||
#ifdef CONFIG_CAN_FD_MODE
|
#ifdef CONFIG_CAN_FD_MODE
|
||||||
bool fd;
|
bool fd;
|
||||||
|
@ -814,8 +1031,90 @@ struct can_mcan_ops {
|
||||||
can_mcan_clear_mram_t clear_mram;
|
can_mcan_clear_mram_t clear_mram;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Bosch M_CAN driver internal Tx callback structure.
|
||||||
|
*/
|
||||||
|
struct can_mcan_tx_callback {
|
||||||
|
can_tx_callback_t function;
|
||||||
|
void *user_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Bosch M_CAN driver internal Rx callback structure.
|
||||||
|
*/
|
||||||
|
struct can_mcan_rx_callback {
|
||||||
|
can_rx_callback_t function;
|
||||||
|
void *user_data;
|
||||||
|
uint8_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Bosch M_CAN driver internal Tx + Rx callbacks structure.
|
||||||
|
*/
|
||||||
|
struct can_mcan_callbacks {
|
||||||
|
struct can_mcan_tx_callback *tx;
|
||||||
|
struct can_mcan_rx_callback *std;
|
||||||
|
struct can_mcan_rx_callback *ext;
|
||||||
|
uint8_t num_tx;
|
||||||
|
uint8_t num_std;
|
||||||
|
uint8_t num_ext;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Define Bosch M_CAN TX and RX callbacks
|
||||||
|
*
|
||||||
|
* This macro allows a Bosch M_CAN driver frontend using a fixed Message RAM configuration to limit
|
||||||
|
* the required software resources (e.g. limit the number of the standard (11-bit) or extended
|
||||||
|
* (29-bit) filters in use).
|
||||||
|
*
|
||||||
|
* Frontend drivers supporting dynamic Message RAM configuration should use @ref
|
||||||
|
* CAN_MCAN_DT_CALLBACKS_DEFINE() or @ref CAN_MCAN_DT_INST_CALLBACKS_DEFINE() instead.
|
||||||
|
*
|
||||||
|
* @param _name callbacks variable name
|
||||||
|
* @param _tx Number of Tx callbacks
|
||||||
|
* @param _std Number of standard (11-bit) filter callbacks
|
||||||
|
* @param _ext Number of extended (29-bit) filter callbacks
|
||||||
|
* @see CAN_MCAN_DT_CALLBACKS_DEFINE()
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_CALLBACKS_DEFINE(_name, _tx, _std, _ext) \
|
||||||
|
static struct can_mcan_tx_callback _name##_tx_cbs[_tx]; \
|
||||||
|
static struct can_mcan_rx_callback _name##_std_cbs[_std]; \
|
||||||
|
static struct can_mcan_rx_callback _name##_ext_cbs[_ext]; \
|
||||||
|
static const struct can_mcan_callbacks _name = { \
|
||||||
|
.tx = _name##_tx_cbs, \
|
||||||
|
.std = _name##_std_cbs, \
|
||||||
|
.ext = _name##_ext_cbs, \
|
||||||
|
.num_tx = _tx, \
|
||||||
|
.num_std = _std, \
|
||||||
|
.num_ext = _ext, \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Define Bosch M_CAN TX and RX callbacks
|
||||||
|
* @param node_id node identifier
|
||||||
|
* @param _name callbacks variable name
|
||||||
|
* @see CAN_MCAN_CALLBACKS_DEFINE()
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_CALLBACKS_DEFINE(node_id, _name) \
|
||||||
|
CAN_MCAN_CALLBACKS_DEFINE(_name, CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(node_id), \
|
||||||
|
CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(node_id), \
|
||||||
|
CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(node_id))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Equivalent to CAN_MCAN_DT_CALLBACKS_DEFINE(DT_DRV_INST(inst))
|
||||||
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
|
* @param _name callbacks variable name
|
||||||
|
* @see CAN_MCAN_DT_CALLBACKS_DEFINE()
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_INST_CALLBACKS_DEFINE(inst, _name) \
|
||||||
|
CAN_MCAN_DT_CALLBACKS_DEFINE(DT_DRV_INST(inst), _name)
|
||||||
|
|
||||||
struct can_mcan_config {
|
struct can_mcan_config {
|
||||||
struct can_mcan_ops *ops;
|
const struct can_mcan_ops *ops;
|
||||||
|
const struct can_mcan_callbacks *callbacks;
|
||||||
|
uint16_t mram_elements[CAN_MCAN_MRAM_CFG_NUM_CELLS];
|
||||||
|
uint16_t mram_offsets[CAN_MCAN_MRAM_CFG_NUM_CELLS];
|
||||||
|
size_t mram_size;
|
||||||
uint32_t bus_speed;
|
uint32_t bus_speed;
|
||||||
uint16_t sjw;
|
uint16_t sjw;
|
||||||
uint16_t sample_point;
|
uint16_t sample_point;
|
||||||
|
@ -834,17 +1133,62 @@ struct can_mcan_config {
|
||||||
const void *custom;
|
const void *custom;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get an array containing the number of elements in Bosch M_CAN Message RAM
|
||||||
|
*
|
||||||
|
* The order of the array entries is given by the @ref CAN_MCAN_MRAM_CFG definitions.
|
||||||
|
*
|
||||||
|
* @param node_id node identifier
|
||||||
|
* @return array of number of elements
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_MRAM_ELEMENTS_GET(node_id) \
|
||||||
|
{ \
|
||||||
|
0, /* offset cell */ \
|
||||||
|
CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(node_id), \
|
||||||
|
CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(node_id), \
|
||||||
|
CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS(node_id), \
|
||||||
|
CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS(node_id), \
|
||||||
|
CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS(node_id), \
|
||||||
|
CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS(node_id), \
|
||||||
|
CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(node_id) \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get an array containing the base offsets for element in Bosch M_CAN Message RAM
|
||||||
|
*
|
||||||
|
* The order of the array entries is given by the @ref CAN_MCAN_MRAM_CFG definitions.
|
||||||
|
*
|
||||||
|
* @param node_id node identifier
|
||||||
|
* @return array of base offsets for elements
|
||||||
|
*/
|
||||||
|
#define CAN_MCAN_DT_MRAM_OFFSETS_GET(node_id) \
|
||||||
|
{ \
|
||||||
|
0, /* offset cell */ \
|
||||||
|
CAN_MCAN_DT_MRAM_STD_FILTER_OFFSET(node_id), \
|
||||||
|
CAN_MCAN_DT_MRAM_EXT_FILTER_OFFSET(node_id), \
|
||||||
|
CAN_MCAN_DT_MRAM_RX_FIFO0_OFFSET(node_id), \
|
||||||
|
CAN_MCAN_DT_MRAM_RX_FIFO1_OFFSET(node_id), \
|
||||||
|
CAN_MCAN_DT_MRAM_RX_BUFFER_OFFSET(node_id), \
|
||||||
|
CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_OFFSET(node_id), \
|
||||||
|
CAN_MCAN_DT_MRAM_TX_BUFFER_OFFSET(node_id) \
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Static initializer for @p can_mcan_config struct
|
* @brief Static initializer for @p can_mcan_config struct
|
||||||
*
|
*
|
||||||
* @param node_id Devicetree node identifier
|
* @param node_id Devicetree node identifier
|
||||||
* @param _custom Pointer to custom driver frontend configuration structure
|
* @param _custom Pointer to custom driver frontend configuration structure
|
||||||
* @param _ops Pointer to front-end @a can_mcan_ops
|
* @param _ops Pointer to front-end @a can_mcan_ops
|
||||||
|
* @param _cbs Pointer to front-end @a can_mcan_callbacks
|
||||||
*/
|
*/
|
||||||
#ifdef CONFIG_CAN_FD_MODE
|
#ifdef CONFIG_CAN_FD_MODE
|
||||||
#define CAN_MCAN_DT_CONFIG_GET(node_id, _custom, _ops) \
|
#define CAN_MCAN_DT_CONFIG_GET(node_id, _custom, _ops, _cbs) \
|
||||||
{ \
|
{ \
|
||||||
.ops = _ops, \
|
.ops = _ops, \
|
||||||
|
.callbacks = _cbs, \
|
||||||
|
.mram_elements = CAN_MCAN_DT_MRAM_ELEMENTS_GET(node_id), \
|
||||||
|
.mram_offsets = CAN_MCAN_DT_MRAM_OFFSETS_GET(node_id), \
|
||||||
|
.mram_size = CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(node_id), \
|
||||||
.bus_speed = DT_PROP(node_id, bus_speed), \
|
.bus_speed = DT_PROP(node_id, bus_speed), \
|
||||||
.sjw = DT_PROP(node_id, sjw), \
|
.sjw = DT_PROP(node_id, sjw), \
|
||||||
.sample_point = DT_PROP_OR(node_id, sample_point, 0), \
|
.sample_point = DT_PROP_OR(node_id, sample_point, 0), \
|
||||||
|
@ -862,9 +1206,13 @@ struct can_mcan_config {
|
||||||
.custom = _custom, \
|
.custom = _custom, \
|
||||||
}
|
}
|
||||||
#else /* CONFIG_CAN_FD_MODE */
|
#else /* CONFIG_CAN_FD_MODE */
|
||||||
#define CAN_MCAN_DT_CONFIG_GET(node_id, _custom, _ops) \
|
#define CAN_MCAN_DT_CONFIG_GET(node_id, _custom, _ops, _cbs) \
|
||||||
{ \
|
{ \
|
||||||
.ops = _ops, \
|
.ops = _ops, \
|
||||||
|
.callbacks = _cbs, \
|
||||||
|
.mram_elements = CAN_MCAN_DT_MRAM_ELEMENTS_GET(node_id), \
|
||||||
|
.mram_offsets = CAN_MCAN_DT_MRAM_OFFSETS_GET(node_id), \
|
||||||
|
.mram_size = CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(node_id), \
|
||||||
.bus_speed = DT_PROP(node_id, bus_speed), \
|
.bus_speed = DT_PROP(node_id, bus_speed), \
|
||||||
.sjw = DT_PROP(node_id, sjw), \
|
.sjw = DT_PROP(node_id, sjw), \
|
||||||
.sample_point = DT_PROP_OR(node_id, sample_point, 0), \
|
.sample_point = DT_PROP_OR(node_id, sample_point, 0), \
|
||||||
|
@ -882,14 +1230,14 @@ struct can_mcan_config {
|
||||||
* @param inst DT_DRV_COMPAT instance number
|
* @param inst DT_DRV_COMPAT instance number
|
||||||
* @param _custom Pointer to custom driver frontend configuration structure
|
* @param _custom Pointer to custom driver frontend configuration structure
|
||||||
* @param _ops Pointer to front-end @a can_mcan_ops
|
* @param _ops Pointer to front-end @a can_mcan_ops
|
||||||
|
* @param _cbs Pointer to front-end @a can_mcan_callbacks
|
||||||
* @see CAN_MCAN_DT_CONFIG_GET()
|
* @see CAN_MCAN_DT_CONFIG_GET()
|
||||||
*/
|
*/
|
||||||
#define CAN_MCAN_DT_CONFIG_INST_GET(inst, _custom, _ops) \
|
#define CAN_MCAN_DT_CONFIG_INST_GET(inst, _custom, _ops, _cbs) \
|
||||||
CAN_MCAN_DT_CONFIG_GET(DT_DRV_INST(inst), _custom, _ops)
|
CAN_MCAN_DT_CONFIG_GET(DT_DRV_INST(inst), _custom, _ops, _cbs)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initializer for a @a can_mcan_data struct
|
* @brief Initializer for a @a can_mcan_data struct
|
||||||
* @param _msg_ram Pointer to message RAM structure
|
|
||||||
* @param _custom Pointer to custom driver frontend data structure
|
* @param _custom Pointer to custom driver frontend data structure
|
||||||
*/
|
*/
|
||||||
#define CAN_MCAN_DATA_INITIALIZER(_custom) \
|
#define CAN_MCAN_DATA_INITIALIZER(_custom) \
|
||||||
|
|
|
@ -23,16 +23,13 @@ LOG_MODULE_REGISTER(can_mcux_mcan, CONFIG_CAN_LOG_LEVEL);
|
||||||
|
|
||||||
struct mcux_mcan_config {
|
struct mcux_mcan_config {
|
||||||
mm_reg_t base;
|
mm_reg_t base;
|
||||||
|
mem_addr_t mram;
|
||||||
const struct device *clock_dev;
|
const struct device *clock_dev;
|
||||||
clock_control_subsys_t clock_subsys;
|
clock_control_subsys_t clock_subsys;
|
||||||
void (*irq_config_func)(const struct device *dev);
|
void (*irq_config_func)(const struct device *dev);
|
||||||
const struct pinctrl_dev_config *pincfg;
|
const struct pinctrl_dev_config *pincfg;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mcux_mcan_data {
|
|
||||||
struct can_mcan_msg_sram msg_ram __nocache;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int mcux_mcan_read_reg(const struct device *dev, uint16_t reg, uint32_t *val)
|
static int mcux_mcan_read_reg(const struct device *dev, uint16_t reg, uint32_t *val)
|
||||||
{
|
{
|
||||||
const struct can_mcan_config *mcan_config = dev->config;
|
const struct can_mcan_config *mcan_config = dev->config;
|
||||||
|
@ -51,27 +48,27 @@ static int mcux_mcan_write_reg(const struct device *dev, uint16_t reg, uint32_t
|
||||||
|
|
||||||
static int mcux_mcan_read_mram(const struct device *dev, uint16_t offset, void *dst, size_t len)
|
static int mcux_mcan_read_mram(const struct device *dev, uint16_t offset, void *dst, size_t len)
|
||||||
{
|
{
|
||||||
struct can_mcan_data *mcan_data = dev->data;
|
const struct can_mcan_config *mcan_config = dev->config;
|
||||||
struct mcux_mcan_data *mcux_data = mcan_data->custom;
|
const struct mcux_mcan_config *mcux_config = mcan_config->custom;
|
||||||
|
|
||||||
return can_mcan_sys_read_mram(POINTER_TO_UINT(&mcux_data->msg_ram), offset, dst, len);
|
return can_mcan_sys_read_mram(mcux_config->mram, offset, dst, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mcux_mcan_write_mram(const struct device *dev, uint16_t offset, const void *src,
|
static int mcux_mcan_write_mram(const struct device *dev, uint16_t offset, const void *src,
|
||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
struct can_mcan_data *mcan_data = dev->data;
|
const struct can_mcan_config *mcan_config = dev->config;
|
||||||
struct mcux_mcan_data *mcux_data = mcan_data->custom;
|
const struct mcux_mcan_config *mcux_config = mcan_config->custom;
|
||||||
|
|
||||||
return can_mcan_sys_write_mram(POINTER_TO_UINT(&mcux_data->msg_ram), offset, src, len);
|
return can_mcan_sys_write_mram(mcux_config->mram, offset, src, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mcux_mcan_clear_mram(const struct device *dev, uint16_t offset, size_t len)
|
static int mcux_mcan_clear_mram(const struct device *dev, uint16_t offset, size_t len)
|
||||||
{
|
{
|
||||||
struct can_mcan_data *mcan_data = dev->data;
|
const struct can_mcan_config *mcan_config = dev->config;
|
||||||
struct mcux_mcan_data *mcux_data = mcan_data->custom;
|
const struct mcux_mcan_config *mcux_config = mcan_config->custom;
|
||||||
|
|
||||||
return can_mcan_sys_clear_mram(POINTER_TO_UINT(&mcux_data->msg_ram), offset, len);
|
return can_mcan_sys_clear_mram(mcux_config->mram, offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mcux_mcan_get_core_clock(const struct device *dev, uint32_t *rate)
|
static int mcux_mcan_get_core_clock(const struct device *dev, uint32_t *rate)
|
||||||
|
@ -87,9 +84,7 @@ static int mcux_mcan_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct can_mcan_config *mcan_config = dev->config;
|
const struct can_mcan_config *mcan_config = dev->config;
|
||||||
const struct mcux_mcan_config *mcux_config = mcan_config->custom;
|
const struct mcux_mcan_config *mcux_config = mcan_config->custom;
|
||||||
struct can_mcan_data *mcan_data = dev->data;
|
const uintptr_t mrba = mcux_config->mram & MCUX_MCAN_MRBA_BA;
|
||||||
struct mcux_mcan_data *mcux_data = mcan_data->custom;
|
|
||||||
const uintptr_t mrba = POINTER_TO_UINT(&mcux_data->msg_ram) & MCUX_MCAN_MRBA_BA;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!device_is_ready(mcux_config->clock_dev)) {
|
if (!device_is_ready(mcux_config->clock_dev)) {
|
||||||
|
@ -113,7 +108,7 @@ static int mcux_mcan_init(const struct device *dev)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = can_mcan_configure_mram(dev, mrba, POINTER_TO_UINT(&mcux_data->msg_ram));
|
err = can_mcan_configure_mram(dev, mrba, mcux_config->mram);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
@ -204,12 +199,17 @@ static const struct can_mcan_ops mcux_mcan_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MCUX_MCAN_INIT(n) \
|
#define MCUX_MCAN_INIT(n) \
|
||||||
|
CAN_MCAN_DT_INST_BUILD_ASSERT_MRAM_CFG(n); \
|
||||||
PINCTRL_DT_INST_DEFINE(n); \
|
PINCTRL_DT_INST_DEFINE(n); \
|
||||||
\
|
\
|
||||||
static void mcux_mcan_irq_config_##n(const struct device *dev); \
|
static void mcux_mcan_irq_config_##n(const struct device *dev); \
|
||||||
\
|
\
|
||||||
|
CAN_MCAN_DT_INST_CALLBACKS_DEFINE(n, mcux_mcan_cbs_##n); \
|
||||||
|
CAN_MCAN_DT_INST_MRAM_DEFINE(n, mcux_mcan_mram_##n); \
|
||||||
|
\
|
||||||
static const struct mcux_mcan_config mcux_mcan_config_##n = { \
|
static const struct mcux_mcan_config mcux_mcan_config_##n = { \
|
||||||
.base = (mm_reg_t)DT_INST_REG_ADDR(n), \
|
.base = CAN_MCAN_DT_INST_MCAN_ADDR(n), \
|
||||||
|
.mram = (mem_addr_t)POINTER_TO_UINT(&mcux_mcan_mram_##n), \
|
||||||
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \
|
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \
|
||||||
.clock_subsys = (clock_control_subsys_t) \
|
.clock_subsys = (clock_control_subsys_t) \
|
||||||
DT_INST_CLOCKS_CELL(n, name), \
|
DT_INST_CLOCKS_CELL(n, name), \
|
||||||
|
@ -219,12 +219,11 @@ static const struct can_mcan_ops mcux_mcan_ops = {
|
||||||
\
|
\
|
||||||
static const struct can_mcan_config can_mcan_config_##n = \
|
static const struct can_mcan_config can_mcan_config_##n = \
|
||||||
CAN_MCAN_DT_CONFIG_INST_GET(n, &mcux_mcan_config_##n, \
|
CAN_MCAN_DT_CONFIG_INST_GET(n, &mcux_mcan_config_##n, \
|
||||||
&mcux_mcan_ops); \
|
&mcux_mcan_ops, \
|
||||||
\
|
&mcux_mcan_cbs_##n); \
|
||||||
static struct mcux_mcan_data mcux_mcan_data_##n; \
|
|
||||||
\
|
\
|
||||||
static struct can_mcan_data can_mcan_data_##n = \
|
static struct can_mcan_data can_mcan_data_##n = \
|
||||||
CAN_MCAN_DATA_INITIALIZER(&mcux_mcan_data_##n); \
|
CAN_MCAN_DATA_INITIALIZER(NULL); \
|
||||||
\
|
\
|
||||||
DEVICE_DT_INST_DEFINE(n, &mcux_mcan_init, NULL, \
|
DEVICE_DT_INST_DEFINE(n, &mcux_mcan_init, NULL, \
|
||||||
&can_mcan_data_##n, \
|
&can_mcan_data_##n, \
|
||||||
|
|
|
@ -21,16 +21,13 @@ LOG_MODULE_REGISTER(can_sam, CONFIG_CAN_LOG_LEVEL);
|
||||||
|
|
||||||
struct can_sam_config {
|
struct can_sam_config {
|
||||||
mm_reg_t base;
|
mm_reg_t base;
|
||||||
|
mem_addr_t mram;
|
||||||
void (*config_irq)(void);
|
void (*config_irq)(void);
|
||||||
const struct atmel_sam_pmc_config clock_cfg;
|
const struct atmel_sam_pmc_config clock_cfg;
|
||||||
const struct pinctrl_dev_config *pcfg;
|
const struct pinctrl_dev_config *pcfg;
|
||||||
int divider;
|
int divider;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct can_sam_data {
|
|
||||||
struct can_mcan_msg_sram msg_ram;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int can_sam_read_reg(const struct device *dev, uint16_t reg, uint32_t *val)
|
static int can_sam_read_reg(const struct device *dev, uint16_t reg, uint32_t *val)
|
||||||
{
|
{
|
||||||
const struct can_mcan_config *mcan_config = dev->config;
|
const struct can_mcan_config *mcan_config = dev->config;
|
||||||
|
@ -49,27 +46,27 @@ static int can_sam_write_reg(const struct device *dev, uint16_t reg, uint32_t va
|
||||||
|
|
||||||
static int can_sam_read_mram(const struct device *dev, uint16_t offset, void *dst, size_t len)
|
static int can_sam_read_mram(const struct device *dev, uint16_t offset, void *dst, size_t len)
|
||||||
{
|
{
|
||||||
struct can_mcan_data *mcan_data = dev->data;
|
const struct can_mcan_config *mcan_config = dev->config;
|
||||||
struct can_sam_data *sam_data = mcan_data->custom;
|
const struct can_sam_config *sam_config = mcan_config->custom;
|
||||||
|
|
||||||
return can_mcan_sys_read_mram(POINTER_TO_UINT(&sam_data->msg_ram), offset, dst, len);
|
return can_mcan_sys_read_mram(sam_config->mram, offset, dst, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int can_sam_write_mram(const struct device *dev, uint16_t offset, const void *src,
|
static int can_sam_write_mram(const struct device *dev, uint16_t offset, const void *src,
|
||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
struct can_mcan_data *mcan_data = dev->data;
|
const struct can_mcan_config *mcan_config = dev->config;
|
||||||
struct can_sam_data *sam_data = mcan_data->custom;
|
const struct can_sam_config *sam_config = mcan_config->custom;
|
||||||
|
|
||||||
return can_mcan_sys_write_mram(POINTER_TO_UINT(&sam_data->msg_ram), offset, src, len);
|
return can_mcan_sys_write_mram(sam_config->mram, offset, src, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int can_sam_clear_mram(const struct device *dev, uint16_t offset, size_t len)
|
static int can_sam_clear_mram(const struct device *dev, uint16_t offset, size_t len)
|
||||||
{
|
{
|
||||||
struct can_mcan_data *mcan_data = dev->data;
|
const struct can_mcan_config *mcan_config = dev->config;
|
||||||
struct can_sam_data *sam_data = mcan_data->custom;
|
const struct can_sam_config *sam_config = mcan_config->custom;
|
||||||
|
|
||||||
return can_mcan_sys_clear_mram(POINTER_TO_UINT(&sam_data->msg_ram), offset, len);
|
return can_mcan_sys_clear_mram(sam_config->mram, offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int can_sam_get_core_clock(const struct device *dev, uint32_t *rate)
|
static int can_sam_get_core_clock(const struct device *dev, uint32_t *rate)
|
||||||
|
@ -96,8 +93,6 @@ static int can_sam_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct can_mcan_config *mcan_cfg = dev->config;
|
const struct can_mcan_config *mcan_cfg = dev->config;
|
||||||
const struct can_sam_config *sam_cfg = mcan_cfg->custom;
|
const struct can_sam_config *sam_cfg = mcan_cfg->custom;
|
||||||
struct can_mcan_data *mcan_data = dev->data;
|
|
||||||
struct can_sam_data *sam_data = mcan_data->custom;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
can_sam_clock_enable(sam_cfg);
|
can_sam_clock_enable(sam_cfg);
|
||||||
|
@ -107,7 +102,7 @@ static int can_sam_init(const struct device *dev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = can_mcan_configure_mram(dev, 0U, POINTER_TO_UINT(&sam_data->msg_ram));
|
ret = can_mcan_configure_mram(dev, 0U, sam_cfg->mram);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -195,8 +190,12 @@ static void config_can_##inst##_irq(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CAN_SAM_CFG_INST(inst) \
|
#define CAN_SAM_CFG_INST(inst) \
|
||||||
|
CAN_MCAN_DT_INST_CALLBACKS_DEFINE(inst, can_sam_cbs_##inst); \
|
||||||
|
CAN_MCAN_DT_INST_MRAM_DEFINE(inst, can_sam_mram_##inst); \
|
||||||
|
\
|
||||||
static const struct can_sam_config can_sam_cfg_##inst = { \
|
static const struct can_sam_config can_sam_cfg_##inst = { \
|
||||||
.base = (mm_reg_t)DT_INST_REG_ADDR(inst), \
|
.base = CAN_MCAN_DT_INST_MCAN_ADDR(inst), \
|
||||||
|
.mram = (mem_addr_t)POINTER_TO_UINT(&can_sam_mram_##inst), \
|
||||||
.clock_cfg = SAM_DT_INST_CLOCK_PMC_CFG(inst), \
|
.clock_cfg = SAM_DT_INST_CLOCK_PMC_CFG(inst), \
|
||||||
.divider = DT_INST_PROP(inst, divider), \
|
.divider = DT_INST_PROP(inst, divider), \
|
||||||
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \
|
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(inst), \
|
||||||
|
@ -205,13 +204,12 @@ static void config_can_##inst##_irq(void)
|
||||||
\
|
\
|
||||||
static const struct can_mcan_config can_mcan_cfg_##inst = \
|
static const struct can_mcan_config can_mcan_cfg_##inst = \
|
||||||
CAN_MCAN_DT_CONFIG_INST_GET(inst, &can_sam_cfg_##inst, \
|
CAN_MCAN_DT_CONFIG_INST_GET(inst, &can_sam_cfg_##inst, \
|
||||||
&can_sam_ops);
|
&can_sam_ops, \
|
||||||
|
&can_sam_cbs_##inst);
|
||||||
|
|
||||||
#define CAN_SAM_DATA_INST(inst) \
|
#define CAN_SAM_DATA_INST(inst) \
|
||||||
static struct can_sam_data can_sam_data_##inst; \
|
|
||||||
\
|
|
||||||
static struct can_mcan_data can_mcan_data_##inst = \
|
static struct can_mcan_data can_mcan_data_##inst = \
|
||||||
CAN_MCAN_DATA_INITIALIZER(&can_sam_data_##inst);
|
CAN_MCAN_DATA_INITIALIZER(NULL);
|
||||||
|
|
||||||
#define CAN_SAM_DEVICE_INST(inst) \
|
#define CAN_SAM_DEVICE_INST(inst) \
|
||||||
DEVICE_DT_INST_DEFINE(inst, &can_sam_init, NULL, \
|
DEVICE_DT_INST_DEFINE(inst, &can_sam_init, NULL, \
|
||||||
|
@ -221,6 +219,7 @@ static void config_can_##inst##_irq(void)
|
||||||
&can_sam_driver_api);
|
&can_sam_driver_api);
|
||||||
|
|
||||||
#define CAN_SAM_INST(inst) \
|
#define CAN_SAM_INST(inst) \
|
||||||
|
CAN_MCAN_DT_INST_BUILD_ASSERT_MRAM_CFG(inst); \
|
||||||
PINCTRL_DT_INST_DEFINE(inst); \
|
PINCTRL_DT_INST_DEFINE(inst); \
|
||||||
CAN_SAM_IRQ_CFG_FUNCTION(inst) \
|
CAN_SAM_IRQ_CFG_FUNCTION(inst) \
|
||||||
CAN_SAM_CFG_INST(inst) \
|
CAN_SAM_CFG_INST(inst) \
|
||||||
|
|
|
@ -21,6 +21,7 @@ LOG_MODULE_REGISTER(can_sam0, CONFIG_CAN_LOG_LEVEL);
|
||||||
|
|
||||||
struct can_sam0_config {
|
struct can_sam0_config {
|
||||||
mm_reg_t base;
|
mm_reg_t base;
|
||||||
|
mem_addr_t mram;
|
||||||
void (*config_irq)(void);
|
void (*config_irq)(void);
|
||||||
const struct pinctrl_dev_config *pcfg;
|
const struct pinctrl_dev_config *pcfg;
|
||||||
volatile uint32_t *mclk;
|
volatile uint32_t *mclk;
|
||||||
|
@ -29,10 +30,6 @@ struct can_sam0_config {
|
||||||
int divider;
|
int divider;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct can_sam0_data {
|
|
||||||
struct can_mcan_msg_sram msg_ram;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int can_sam0_read_reg(const struct device *dev, uint16_t reg, uint32_t *val)
|
static int can_sam0_read_reg(const struct device *dev, uint16_t reg, uint32_t *val)
|
||||||
{
|
{
|
||||||
const struct can_mcan_config *mcan_config = dev->config;
|
const struct can_mcan_config *mcan_config = dev->config;
|
||||||
|
@ -65,27 +62,27 @@ static int can_sam0_write_reg(const struct device *dev, uint16_t reg, uint32_t v
|
||||||
|
|
||||||
static int can_sam0_read_mram(const struct device *dev, uint16_t offset, void *dst, size_t len)
|
static int can_sam0_read_mram(const struct device *dev, uint16_t offset, void *dst, size_t len)
|
||||||
{
|
{
|
||||||
struct can_mcan_data *mcan_data = dev->data;
|
const struct can_mcan_config *mcan_config = dev->config;
|
||||||
struct can_sam0_data *sam_data = mcan_data->custom;
|
const struct can_sam0_config *sam_config = mcan_config->custom;
|
||||||
|
|
||||||
return can_mcan_sys_read_mram(POINTER_TO_UINT(&sam_data->msg_ram), offset, dst, len);
|
return can_mcan_sys_read_mram(sam_config->mram, offset, dst, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int can_sam0_write_mram(const struct device *dev, uint16_t offset, const void *src,
|
static int can_sam0_write_mram(const struct device *dev, uint16_t offset, const void *src,
|
||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
struct can_mcan_data *mcan_data = dev->data;
|
const struct can_mcan_config *mcan_config = dev->config;
|
||||||
struct can_sam0_data *sam_data = mcan_data->custom;
|
const struct can_sam0_config *sam_config = mcan_config->custom;
|
||||||
|
|
||||||
return can_mcan_sys_write_mram(POINTER_TO_UINT(&sam_data->msg_ram), offset, src, len);
|
return can_mcan_sys_write_mram(sam_config->mram, offset, src, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int can_sam0_clear_mram(const struct device *dev, uint16_t offset, size_t len)
|
static int can_sam0_clear_mram(const struct device *dev, uint16_t offset, size_t len)
|
||||||
{
|
{
|
||||||
struct can_mcan_data *mcan_data = dev->data;
|
const struct can_mcan_config *mcan_config = dev->config;
|
||||||
struct can_sam0_data *sam_data = mcan_data->custom;
|
const struct can_sam0_config *sam_config = mcan_config->custom;
|
||||||
|
|
||||||
return can_mcan_sys_clear_mram(POINTER_TO_UINT(&sam_data->msg_ram), offset, len);
|
return can_mcan_sys_clear_mram(sam_config->mram, offset, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void can_sam0_line_x_isr(const struct device *dev)
|
void can_sam0_line_x_isr(const struct device *dev)
|
||||||
|
@ -123,8 +120,6 @@ static int can_sam0_init(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct can_mcan_config *mcan_cfg = dev->config;
|
const struct can_mcan_config *mcan_cfg = dev->config;
|
||||||
const struct can_sam0_config *sam_cfg = mcan_cfg->custom;
|
const struct can_sam0_config *sam_cfg = mcan_cfg->custom;
|
||||||
struct can_mcan_data *mcan_data = dev->data;
|
|
||||||
struct can_sam0_data *sam_data = mcan_data->custom;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
can_sam0_clock_enable(sam_cfg);
|
can_sam0_clock_enable(sam_cfg);
|
||||||
|
@ -135,7 +130,7 @@ static int can_sam0_init(const struct device *dev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = can_mcan_configure_mram(dev, 0U, POINTER_TO_UINT(&sam_data->msg_ram));
|
ret = can_mcan_configure_mram(dev, 0U, sam_cfg->mram);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
LOG_ERR("failed to configure message ram");
|
LOG_ERR("failed to configure message ram");
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -221,8 +216,12 @@ static void config_can_##inst##_irq(void) \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CAN_SAM0_CFG_INST(inst) \
|
#define CAN_SAM0_CFG_INST(inst) \
|
||||||
|
CAN_MCAN_DT_INST_CALLBACKS_DEFINE(inst, can_sam0_cbs_##inst); \
|
||||||
|
CAN_MCAN_DT_INST_MRAM_DEFINE(inst, can_sam0_mram_##inst); \
|
||||||
|
\
|
||||||
static const struct can_sam0_config can_sam0_cfg_##inst = { \
|
static const struct can_sam0_config can_sam0_cfg_##inst = { \
|
||||||
.base = (mm_reg_t)DT_INST_REG_ADDR(inst), \
|
.base = CAN_MCAN_DT_INST_MCAN_ADDR(inst), \
|
||||||
|
.mram = (mem_addr_t)POINTER_TO_UINT(&can_sam0_mram_##inst), \
|
||||||
.mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(inst), \
|
.mclk = (volatile uint32_t *)MCLK_MASK_DT_INT_REG_ADDR(inst), \
|
||||||
.mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(inst, mclk, bit)), \
|
.mclk_mask = BIT(DT_INST_CLOCKS_CELL_BY_NAME(inst, mclk, bit)), \
|
||||||
.gclk_core_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, periph_ch), \
|
.gclk_core_id = DT_INST_CLOCKS_CELL_BY_NAME(inst, gclk, periph_ch), \
|
||||||
|
@ -232,13 +231,12 @@ static void config_can_##inst##_irq(void) \
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
static const struct can_mcan_config can_mcan_cfg_##inst = \
|
static const struct can_mcan_config can_mcan_cfg_##inst = \
|
||||||
CAN_MCAN_DT_CONFIG_INST_GET(inst, &can_sam0_cfg_##inst, &can_sam0_ops);
|
CAN_MCAN_DT_CONFIG_INST_GET(inst, &can_sam0_cfg_##inst, &can_sam0_ops, \
|
||||||
|
&can_sam0_cbs_##inst);
|
||||||
|
|
||||||
#define CAN_SAM0_DATA_INST(inst) \
|
#define CAN_SAM0_DATA_INST(inst) \
|
||||||
static struct can_sam0_data can_sam0_data_##inst; \
|
|
||||||
\
|
|
||||||
static struct can_mcan_data can_mcan_data_##inst = \
|
static struct can_mcan_data can_mcan_data_##inst = \
|
||||||
CAN_MCAN_DATA_INITIALIZER(&can_sam0_data_##inst);
|
CAN_MCAN_DATA_INITIALIZER(NULL);
|
||||||
|
|
||||||
#define CAN_SAM0_DEVICE_INST(inst) \
|
#define CAN_SAM0_DEVICE_INST(inst) \
|
||||||
DEVICE_DT_INST_DEFINE(inst, &can_sam0_init, NULL, \
|
DEVICE_DT_INST_DEFINE(inst, &can_sam0_init, NULL, \
|
||||||
|
@ -248,6 +246,7 @@ static void config_can_##inst##_irq(void) \
|
||||||
&can_sam0_driver_api);
|
&can_sam0_driver_api);
|
||||||
|
|
||||||
#define CAN_SAM0_INST(inst) \
|
#define CAN_SAM0_INST(inst) \
|
||||||
|
CAN_MCAN_DT_INST_BUILD_ASSERT_MRAM_CFG(inst); \
|
||||||
PINCTRL_DT_INST_DEFINE(inst); \
|
PINCTRL_DT_INST_DEFINE(inst); \
|
||||||
CAN_SAM0_IRQ_CFG_FUNCTION(inst) \
|
CAN_SAM0_IRQ_CFG_FUNCTION(inst) \
|
||||||
CAN_SAM0_CFG_INST(inst) \
|
CAN_SAM0_CFG_INST(inst) \
|
||||||
|
|
|
@ -635,14 +635,21 @@ static const struct can_mcan_ops can_stm32fd_ops = {
|
||||||
.clear_mram = can_stm32fd_clear_mram,
|
.clear_mram = can_stm32fd_clear_mram,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Assert that the Message RAM configuration matches the fixed hardware configuration */
|
#define CAN_STM32FD_BUILD_ASSERT_MRAM_CFG(inst) \
|
||||||
BUILD_ASSERT(NUM_STD_FILTER_ELEMENTS == 28, "Standard filter elements must be 28");
|
BUILD_ASSERT(CAN_MCAN_DT_INST_MRAM_STD_FILTER_ELEMENTS(inst) == 28, \
|
||||||
BUILD_ASSERT(NUM_EXT_FILTER_ELEMENTS == 8, "Extended filter elements must be 8");
|
"Standard filter elements must be 28"); \
|
||||||
BUILD_ASSERT(NUM_RX_FIFO0_ELEMENTS == 3, "Rx FIFO 0 elements must be 3");
|
BUILD_ASSERT(CAN_MCAN_DT_INST_MRAM_EXT_FILTER_ELEMENTS(inst) == 8, \
|
||||||
BUILD_ASSERT(NUM_RX_FIFO1_ELEMENTS == 3, "Rx FIFO 1 elements must be 3");
|
"Extended filter elements must be 8"); \
|
||||||
BUILD_ASSERT(NUM_RX_BUF_ELEMENTS == 0, "Rx Buffer elements must be 0");
|
BUILD_ASSERT(CAN_MCAN_DT_INST_MRAM_RX_FIFO0_ELEMENTS(inst) == 3, \
|
||||||
BUILD_ASSERT(NUM_TX_EVENT_FIFO_ELEMENTS == 3, "Tx Event FIFO elements must be 3");
|
"Rx FIFO 0 elements must be 3"); \
|
||||||
BUILD_ASSERT(NUM_TX_BUF_ELEMENTS == 3, "Tx Buffer elements must be 0");
|
BUILD_ASSERT(CAN_MCAN_DT_INST_MRAM_RX_FIFO1_ELEMENTS(inst) == 3, \
|
||||||
|
"Rx FIFO 1 elements must be 3"); \
|
||||||
|
BUILD_ASSERT(CAN_MCAN_DT_INST_MRAM_RX_BUFFER_ELEMENTS(inst) == 0, \
|
||||||
|
"Rx Buffer elements must be 0"); \
|
||||||
|
BUILD_ASSERT(CAN_MCAN_DT_INST_MRAM_TX_EVENT_FIFO_ELEMENTS(inst) == 3, \
|
||||||
|
"Tx Event FIFO elements must be 3"); \
|
||||||
|
BUILD_ASSERT(CAN_MCAN_DT_INST_MRAM_TX_BUFFER_ELEMENTS(inst) == 3, \
|
||||||
|
"Tx Buffer elements must be 0");
|
||||||
|
|
||||||
#define CAN_STM32FD_IRQ_CFG_FUNCTION(inst) \
|
#define CAN_STM32FD_IRQ_CFG_FUNCTION(inst) \
|
||||||
static void config_can_##inst##_irq(void) \
|
static void config_can_##inst##_irq(void) \
|
||||||
|
@ -659,13 +666,22 @@ static void config_can_##inst##_irq(void) \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CAN_STM32FD_CFG_INST(inst) \
|
#define CAN_STM32FD_CFG_INST(inst) \
|
||||||
|
BUILD_ASSERT(CAN_MCAN_DT_INST_MRAM_ELEMENTS_SIZE(inst) <= \
|
||||||
|
CAN_MCAN_DT_INST_MRAM_SIZE(inst), \
|
||||||
|
"Insufficient Message RAM size to hold elements"); \
|
||||||
|
\
|
||||||
PINCTRL_DT_INST_DEFINE(inst); \
|
PINCTRL_DT_INST_DEFINE(inst); \
|
||||||
|
CAN_MCAN_CALLBACKS_DEFINE(can_stm32fd_cbs_##inst, \
|
||||||
|
CAN_MCAN_DT_INST_MRAM_TX_BUFFER_ELEMENTS(inst), \
|
||||||
|
CONFIG_CAN_MAX_STD_ID_FILTER, \
|
||||||
|
CONFIG_CAN_MAX_EXT_ID_FILTER); \
|
||||||
|
\
|
||||||
static const struct stm32_pclken can_stm32fd_pclken_##inst[] = \
|
static const struct stm32_pclken can_stm32fd_pclken_##inst[] = \
|
||||||
STM32_DT_INST_CLOCKS(inst); \
|
STM32_DT_INST_CLOCKS(inst); \
|
||||||
\
|
\
|
||||||
static const struct can_stm32fd_config can_stm32fd_cfg_##inst = { \
|
static const struct can_stm32fd_config can_stm32fd_cfg_##inst = { \
|
||||||
.base = (mm_reg_t)DT_INST_REG_ADDR_BY_NAME(inst, m_can), \
|
.base = CAN_MCAN_DT_INST_MCAN_ADDR(inst), \
|
||||||
.mram = (mem_addr_t)DT_INST_REG_ADDR_BY_NAME(inst, message_ram), \
|
.mram = CAN_MCAN_DT_INST_MRAM_ADDR(inst), \
|
||||||
.pclken = can_stm32fd_pclken_##inst, \
|
.pclken = can_stm32fd_pclken_##inst, \
|
||||||
.pclk_len = DT_INST_NUM_CLOCKS(inst), \
|
.pclk_len = DT_INST_NUM_CLOCKS(inst), \
|
||||||
.config_irq = config_can_##inst##_irq, \
|
.config_irq = config_can_##inst##_irq, \
|
||||||
|
@ -675,7 +691,8 @@ static void config_can_##inst##_irq(void) \
|
||||||
\
|
\
|
||||||
static const struct can_mcan_config can_mcan_cfg_##inst = \
|
static const struct can_mcan_config can_mcan_cfg_##inst = \
|
||||||
CAN_MCAN_DT_CONFIG_INST_GET(inst, &can_stm32fd_cfg_##inst, \
|
CAN_MCAN_DT_CONFIG_INST_GET(inst, &can_stm32fd_cfg_##inst, \
|
||||||
&can_stm32fd_ops);
|
&can_stm32fd_ops, \
|
||||||
|
&can_stm32fd_cbs_##inst);
|
||||||
|
|
||||||
#define CAN_STM32FD_DATA_INST(inst) \
|
#define CAN_STM32FD_DATA_INST(inst) \
|
||||||
static struct can_mcan_data can_mcan_data_##inst = \
|
static struct can_mcan_data can_mcan_data_##inst = \
|
||||||
|
@ -688,6 +705,7 @@ static void config_can_##inst##_irq(void) \
|
||||||
&can_stm32fd_driver_api);
|
&can_stm32fd_driver_api);
|
||||||
|
|
||||||
#define CAN_STM32FD_INST(inst) \
|
#define CAN_STM32FD_INST(inst) \
|
||||||
|
CAN_STM32FD_BUILD_ASSERT_MRAM_CFG(inst) \
|
||||||
CAN_STM32FD_IRQ_CFG_FUNCTION(inst) \
|
CAN_STM32FD_IRQ_CFG_FUNCTION(inst) \
|
||||||
CAN_STM32FD_CFG_INST(inst) \
|
CAN_STM32FD_CFG_INST(inst) \
|
||||||
CAN_STM32FD_DATA_INST(inst) \
|
CAN_STM32FD_DATA_INST(inst) \
|
||||||
|
|
|
@ -215,13 +215,19 @@ static const struct can_mcan_ops can_stm32h7_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CAN_STM32H7_MCAN_INIT(n) \
|
#define CAN_STM32H7_MCAN_INIT(n) \
|
||||||
|
CAN_MCAN_DT_INST_BUILD_ASSERT_MRAM_CFG(n); \
|
||||||
|
BUILD_ASSERT(CAN_MCAN_DT_INST_MRAM_ELEMENTS_SIZE(n) <= \
|
||||||
|
CAN_MCAN_DT_INST_MRAM_SIZE(n), \
|
||||||
|
"Insufficient Message RAM size to hold elements"); \
|
||||||
|
\
|
||||||
static void stm32h7_mcan_irq_config_##n(void); \
|
static void stm32h7_mcan_irq_config_##n(void); \
|
||||||
\
|
\
|
||||||
PINCTRL_DT_INST_DEFINE(n); \
|
PINCTRL_DT_INST_DEFINE(n); \
|
||||||
|
CAN_MCAN_DT_INST_CALLBACKS_DEFINE(n, can_stm32h7_cbs_##n); \
|
||||||
\
|
\
|
||||||
static const struct can_stm32h7_config can_stm32h7_cfg_##n = { \
|
static const struct can_stm32h7_config can_stm32h7_cfg_##n = { \
|
||||||
.base = (mm_reg_t)DT_INST_REG_ADDR_BY_NAME(n, m_can), \
|
.base = CAN_MCAN_DT_INST_MCAN_ADDR(n), \
|
||||||
.mram = (mem_addr_t)DT_INST_REG_ADDR_BY_NAME(n, message_ram), \
|
.mram = CAN_MCAN_DT_INST_MRAM_ADDR(n), \
|
||||||
.config_irq = stm32h7_mcan_irq_config_##n, \
|
.config_irq = stm32h7_mcan_irq_config_##n, \
|
||||||
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
|
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \
|
||||||
.pclken = { \
|
.pclken = { \
|
||||||
|
@ -232,7 +238,8 @@ static const struct can_mcan_ops can_stm32h7_ops = {
|
||||||
\
|
\
|
||||||
static const struct can_mcan_config can_mcan_cfg_##n = \
|
static const struct can_mcan_config can_mcan_cfg_##n = \
|
||||||
CAN_MCAN_DT_CONFIG_INST_GET(n, &can_stm32h7_cfg_##n, \
|
CAN_MCAN_DT_CONFIG_INST_GET(n, &can_stm32h7_cfg_##n, \
|
||||||
&can_stm32h7_ops); \
|
&can_stm32h7_ops, \
|
||||||
|
&can_stm32h7_cbs_##n); \
|
||||||
\
|
\
|
||||||
static struct can_mcan_data can_mcan_data_##n = \
|
static struct can_mcan_data can_mcan_data_##n = \
|
||||||
CAN_MCAN_DATA_INITIALIZER(NULL); \
|
CAN_MCAN_DATA_INITIALIZER(NULL); \
|
||||||
|
|
|
@ -44,12 +44,6 @@
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
can {
|
|
||||||
compatible = "bosch,m_can-base";
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>;
|
|
||||||
|
|
||||||
can0: can@42001c00 {
|
can0: can@42001c00 {
|
||||||
compatible = "atmel,sam0-can";
|
compatible = "atmel,sam0-can";
|
||||||
reg = <0x42001c00 0x100>;
|
reg = <0x42001c00 0x100>;
|
||||||
|
@ -57,6 +51,7 @@
|
||||||
interrupt-names = "LINE_0";
|
interrupt-names = "LINE_0";
|
||||||
clocks = <&gclk 26>, <&mclk 0x10 8>;
|
clocks = <&gclk 26>, <&mclk 0x10 8>;
|
||||||
clock-names = "GCLK", "MCLK";
|
clock-names = "GCLK", "MCLK";
|
||||||
|
bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>;
|
||||||
divider = <12>;
|
divider = <12>;
|
||||||
sjw = <1>;
|
sjw = <1>;
|
||||||
sample-point = <875>;
|
sample-point = <875>;
|
||||||
|
@ -72,6 +67,7 @@
|
||||||
interrupt-names = "LINE_0";
|
interrupt-names = "LINE_0";
|
||||||
clocks = <&gclk 27>, <&mclk 0x10 9>;
|
clocks = <&gclk 27>, <&mclk 0x10 9>;
|
||||||
clock-names = "GCLK", "MCLK";
|
clock-names = "GCLK", "MCLK";
|
||||||
|
bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>;
|
||||||
divider = <12>;
|
divider = <12>;
|
||||||
sjw = <1>;
|
sjw = <1>;
|
||||||
sample-point = <875>;
|
sample-point = <875>;
|
||||||
|
@ -80,5 +76,4 @@
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -408,12 +408,6 @@
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
can {
|
|
||||||
compatible = "bosch,m_can-base";
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>;
|
|
||||||
|
|
||||||
can0: can@40030000 {
|
can0: can@40030000 {
|
||||||
compatible = "atmel,sam-can";
|
compatible = "atmel,sam-can";
|
||||||
reg = <0x40030000 0x100>;
|
reg = <0x40030000 0x100>;
|
||||||
|
@ -421,6 +415,7 @@
|
||||||
interrupt-names = "LINE_0", "LINE_1";
|
interrupt-names = "LINE_0", "LINE_1";
|
||||||
clocks = <&pmc PMC_TYPE_PERIPHERAL 35>;
|
clocks = <&pmc PMC_TYPE_PERIPHERAL 35>;
|
||||||
divider = <6>;
|
divider = <6>;
|
||||||
|
bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>;
|
||||||
sjw = <1>;
|
sjw = <1>;
|
||||||
sample-point = <875>;
|
sample-point = <875>;
|
||||||
sjw-data = <1>;
|
sjw-data = <1>;
|
||||||
|
@ -435,13 +430,13 @@
|
||||||
interrupt-names = "LINE_0", "LINE_1";
|
interrupt-names = "LINE_0", "LINE_1";
|
||||||
clocks = <&pmc PMC_TYPE_PERIPHERAL 37>;
|
clocks = <&pmc PMC_TYPE_PERIPHERAL 37>;
|
||||||
divider = <6>;
|
divider = <6>;
|
||||||
|
bosch,mram-cfg = <0x0 28 8 3 3 0 1 1>;
|
||||||
sjw = <1>;
|
sjw = <1>;
|
||||||
sample-point = <875>;
|
sample-point = <875>;
|
||||||
sjw-data = <1>;
|
sjw-data = <1>;
|
||||||
sample-point-data = <875>;
|
sample-point-data = <875>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
rstc: rstc@400e1800 {
|
rstc: rstc@400e1800 {
|
||||||
compatible = "atmel,sam-rstc";
|
compatible = "atmel,sam-rstc";
|
||||||
|
|
|
@ -30,25 +30,19 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
can {
|
|
||||||
compatible = "bosch,m_can-base";
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
bosch,mram-cfg = <0x0 28 8 3 3 0 3 3>;
|
|
||||||
|
|
||||||
can1: can@40006400 {
|
can1: can@40006400 {
|
||||||
compatible = "st,stm32-fdcan";
|
compatible = "st,stm32-fdcan";
|
||||||
reg = <0x40006400 0x400>, <0x4000B400 0x350>;
|
reg = <0x40006400 0x400>, <0x4000b400 0x350>;
|
||||||
reg-names = "m_can", "message_ram";
|
reg-names = "m_can", "message_ram";
|
||||||
interrupts = <21 0>, <22 0>;
|
interrupts = <21 0>, <22 0>;
|
||||||
interrupt-names = "LINE_0", "LINE_1";
|
interrupt-names = "LINE_0", "LINE_1";
|
||||||
clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00001000>;
|
clocks = <&rcc STM32_CLOCK_BUS_APB1 0x00001000>;
|
||||||
status = "disabled";
|
bosch,mram-cfg = <0x0 28 8 3 3 0 3 3>;
|
||||||
sjw = <1>;
|
sjw = <1>;
|
||||||
sample-point = <875>;
|
sample-point = <875>;
|
||||||
sjw-data = <1>;
|
sjw-data = <1>;
|
||||||
sample-point-data = <875>;
|
sample-point-data = <875>;
|
||||||
};
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
usart5: serial@40005000 {
|
usart5: serial@40005000 {
|
||||||
|
|
|
@ -381,25 +381,19 @@
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
can {
|
|
||||||
compatible = "bosch,m_can-base";
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
bosch,mram-cfg = <0x0 28 8 3 3 0 3 3>;
|
|
||||||
|
|
||||||
can1: can@40006400 {
|
can1: can@40006400 {
|
||||||
compatible = "st,stm32-fdcan";
|
compatible = "st,stm32-fdcan";
|
||||||
reg = <0x40006400 0x400>, <0x4000A400 0x350>;
|
reg = <0x40006400 0x400>, <0x4000a400 0x350>;
|
||||||
reg-names = "m_can", "message_ram";
|
reg-names = "m_can", "message_ram";
|
||||||
interrupts = <21 0>, <22 0>;
|
interrupts = <21 0>, <22 0>;
|
||||||
interrupt-names = "LINE_0", "LINE_1";
|
interrupt-names = "LINE_0", "LINE_1";
|
||||||
clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>;
|
clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>;
|
||||||
status = "disabled";
|
bosch,mram-cfg = <0x0 28 8 3 3 0 3 3>;
|
||||||
sjw = <1>;
|
sjw = <1>;
|
||||||
sample-point = <875>;
|
sample-point = <875>;
|
||||||
sjw-data = <1>;
|
sjw-data = <1>;
|
||||||
sample-point-data = <875>;
|
sample-point-data = <875>;
|
||||||
};
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
lptim1: timers@40007c00 {
|
lptim1: timers@40007c00 {
|
||||||
|
|
|
@ -84,20 +84,19 @@
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
can {
|
can3: can@40006c00 {
|
||||||
can3: can@40006C00 {
|
|
||||||
compatible = "st,stm32-fdcan";
|
compatible = "st,stm32-fdcan";
|
||||||
reg = <0x40006C00 0x400>, <0x4000AAA0 0x350>;
|
reg = <0x40006c00 0x400>, <0x4000a400 0x9f0>;
|
||||||
reg-names = "m_can", "message_ram";
|
reg-names = "m_can", "message_ram";
|
||||||
interrupts = <88 0>, <89 0>;
|
interrupts = <88 0>, <89 0>;
|
||||||
interrupt-names = "LINE_0", "LINE_1";
|
interrupt-names = "LINE_0", "LINE_1";
|
||||||
clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>;
|
clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>;
|
||||||
status = "disabled";
|
bosch,mram-cfg = <0x6a0 28 8 3 3 0 3 3>;
|
||||||
sjw = <1>;
|
sjw = <1>;
|
||||||
sample-point = <875>;
|
sample-point = <875>;
|
||||||
sjw-data = <1>;
|
sjw-data = <1>;
|
||||||
sample-point-data = <875>;
|
sample-point-data = <875>;
|
||||||
};
|
status = "disabled";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,20 +10,19 @@
|
||||||
soc {
|
soc {
|
||||||
compatible = "st,stm32g491", "st,stm32g4", "simple-bus";
|
compatible = "st,stm32g491", "st,stm32g4", "simple-bus";
|
||||||
|
|
||||||
can {
|
|
||||||
can2: can@40006800 {
|
can2: can@40006800 {
|
||||||
compatible = "st,stm32-fdcan";
|
compatible = "st,stm32-fdcan";
|
||||||
reg = <0x40006800 0x400>, <0x4000A750 0x350>;
|
reg = <0x40006800 0x400>, <0x4000a400 0x6a0>;
|
||||||
reg-names = "m_can", "message_ram";
|
reg-names = "m_can", "message_ram";
|
||||||
interrupts = <86 0>, <87 0>;
|
interrupts = <86 0>, <87 0>;
|
||||||
interrupt-names = "LINE_0", "LINE_1";
|
interrupt-names = "LINE_0", "LINE_1";
|
||||||
clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>;
|
clocks = <&rcc STM32_CLOCK_BUS_APB1 0x02000000>;
|
||||||
status = "disabled";
|
|
||||||
sjw = <1>;
|
sjw = <1>;
|
||||||
|
bosch,mram-cfg = <0x350 28 8 3 3 0 3 3>;
|
||||||
sample-point = <875>;
|
sample-point = <875>;
|
||||||
sjw-data = <1>;
|
sjw-data = <1>;
|
||||||
sample-point-data = <875>;
|
sample-point-data = <875>;
|
||||||
};
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
timers20: timers@40015000 {
|
timers20: timers@40015000 {
|
||||||
|
|
|
@ -436,12 +436,6 @@
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
can {
|
|
||||||
compatible = "bosch,m_can-base";
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
bosch,mram-cfg = <0x0 28 8 3 3 0 3 3>;
|
|
||||||
|
|
||||||
can1: can@4000a400 {
|
can1: can@4000a400 {
|
||||||
compatible = "st,stm32-fdcan";
|
compatible = "st,stm32-fdcan";
|
||||||
reg = <0x4000a400 0x400>, <0x4000ac00 0x350>;
|
reg = <0x4000a400 0x400>, <0x4000ac00 0x350>;
|
||||||
|
@ -449,12 +443,12 @@
|
||||||
interrupts = <39 0>, <40 0>;
|
interrupts = <39 0>, <40 0>;
|
||||||
interrupt-names = "LINE_0", "LINE_1";
|
interrupt-names = "LINE_0", "LINE_1";
|
||||||
clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000200>;
|
clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000200>;
|
||||||
status = "disabled";
|
bosch,mram-cfg = <0x0 28 8 3 3 0 3 3>;
|
||||||
sjw = <1>;
|
sjw = <1>;
|
||||||
sample-point = <875>;
|
sample-point = <875>;
|
||||||
sjw-data = <1>;
|
sjw-data = <1>;
|
||||||
sample-point-data = <875>;
|
sample-point-data = <875>;
|
||||||
};
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
rng: rng@420c0800 {
|
rng: rng@420c0800 {
|
||||||
|
|
|
@ -293,21 +293,20 @@
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
can {
|
|
||||||
can2: can@4000a800 {
|
can2: can@4000a800 {
|
||||||
compatible = "st,stm32-fdcan";
|
compatible = "st,stm32-fdcan";
|
||||||
reg = <0x4000a800 0x400>, <0x4000af50 0x350>;
|
reg = <0x4000a800 0x400>, <0x4000ac00 0x6a0>;
|
||||||
reg-names = "m_can", "message_ram";
|
reg-names = "m_can", "message_ram";
|
||||||
interrupts = <109 0>, <110 0>;
|
interrupts = <109 0>, <110 0>;
|
||||||
interrupt-names = "LINE_0", "LINE_1";
|
interrupt-names = "LINE_0", "LINE_1";
|
||||||
/* common clock FDCAN 1 & 2 */
|
/* common clock FDCAN 1 & 2 */
|
||||||
clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000200>;
|
clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000200>;
|
||||||
status = "disabled";
|
bosch,mram-cfg = <0x350 28 8 3 3 0 3 3>;
|
||||||
sjw = <1>;
|
sjw = <1>;
|
||||||
sample-point = <875>;
|
sample-point = <875>;
|
||||||
sjw-data = <1>;
|
sjw-data = <1>;
|
||||||
sample-point-data = <875>;
|
sample-point-data = <875>;
|
||||||
};
|
status = "disabled";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -465,12 +465,6 @@
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
can {
|
|
||||||
compatible = "bosch,m_can-base";
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
bosch,mram-cfg = <0x0 28 8 3 3 0 3 3>;
|
|
||||||
|
|
||||||
can1: can@4000a000 {
|
can1: can@4000a000 {
|
||||||
compatible = "st,stm32h7-fdcan";
|
compatible = "st,stm32h7-fdcan";
|
||||||
reg = <0x4000a000 0x400>, <0x4000ac00 0x350>;
|
reg = <0x4000a000 0x400>, <0x4000ac00 0x350>;
|
||||||
|
@ -478,26 +472,27 @@
|
||||||
clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000100>;
|
clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000100>;
|
||||||
interrupts = <19 0>, <21 0>, <63 0>;
|
interrupts = <19 0>, <21 0>, <63 0>;
|
||||||
interrupt-names = "LINE_0", "LINE_1", "CALIB";
|
interrupt-names = "LINE_0", "LINE_1", "CALIB";
|
||||||
status = "disabled";
|
bosch,mram-cfg = <0x0 28 8 3 3 0 3 3>;
|
||||||
sjw = <1>;
|
sjw = <1>;
|
||||||
sample-point = <875>;
|
sample-point = <875>;
|
||||||
sjw-data = <1>;
|
sjw-data = <1>;
|
||||||
sample-point-data = <875>;
|
sample-point-data = <875>;
|
||||||
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
can2: can@4000a400 {
|
can2: can@4000a400 {
|
||||||
compatible = "st,stm32h7-fdcan";
|
compatible = "st,stm32h7-fdcan";
|
||||||
reg = <0x4000a400 0x400>, <0x4000ac00 0x350>;
|
reg = <0x4000a400 0x400>, <0x4000ac00 0x6a0>;
|
||||||
reg-names = "m_can", "message_ram";
|
reg-names = "m_can", "message_ram";
|
||||||
clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000100>;
|
clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000100>;
|
||||||
interrupts = <20 0>, <22 0>, <63 0>;
|
interrupts = <20 0>, <22 0>, <63 0>;
|
||||||
interrupt-names = "LINE_0", "LINE_1", "CALIB";
|
interrupt-names = "LINE_0", "LINE_1", "CALIB";
|
||||||
status = "disabled";
|
bosch,mram-cfg = <0x350 28 8 3 3 0 3 3>;
|
||||||
sjw = <1>;
|
sjw = <1>;
|
||||||
sample-point = <875>;
|
sample-point = <875>;
|
||||||
sjw-data = <1>;
|
sjw-data = <1>;
|
||||||
sample-point-data = <875>;
|
sample-point-data = <875>;
|
||||||
};
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
timers1: timers@40010000 {
|
timers1: timers@40010000 {
|
||||||
|
|
|
@ -117,21 +117,20 @@
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
can {
|
can3: can@4000d400 {
|
||||||
can3: can@4000D400 {
|
|
||||||
compatible = "st,stm32h7-fdcan";
|
compatible = "st,stm32h7-fdcan";
|
||||||
reg = <0x4000D400 0x400>, <0x4000ac00 0x350>;
|
reg = <0x4000d400 0x400>, <0x4000ac00 0x9f0>;
|
||||||
reg-names = "m_can", "message_ram";
|
reg-names = "m_can", "message_ram";
|
||||||
clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000100>;
|
clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000100>;
|
||||||
interrupts = <159 0>, <160 0>, <63 0>;
|
interrupts = <159 0>, <160 0>, <63 0>;
|
||||||
interrupt-names = "LINE_0", "LINE_1", "CALIB";
|
interrupt-names = "LINE_0", "LINE_1", "CALIB";
|
||||||
|
bosch,mram-cfg = <0x6a0 28 8 3 3 0 3 3>;
|
||||||
sjw = <1>;
|
sjw = <1>;
|
||||||
sample-point = <875>;
|
sample-point = <875>;
|
||||||
sjw-data = <1>;
|
sjw-data = <1>;
|
||||||
sample-point-data = <875>;
|
sample-point-data = <875>;
|
||||||
status = "disabled";
|
status = "disabled";
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
rtc@58004000 {
|
rtc@58004000 {
|
||||||
bbram: backup_regs {
|
bbram: backup_regs {
|
||||||
|
|
|
@ -770,12 +770,6 @@
|
||||||
num-sampling-time-common-channels = <2>;
|
num-sampling-time-common-channels = <2>;
|
||||||
};
|
};
|
||||||
|
|
||||||
can {
|
|
||||||
compatible = "bosch,m_can-base";
|
|
||||||
#address-cells = <1>;
|
|
||||||
#size-cells = <1>;
|
|
||||||
bosch,mram-cfg = <0x0 28 8 3 3 0 3 3>;
|
|
||||||
|
|
||||||
can1: can@4000a400 {
|
can1: can@4000a400 {
|
||||||
compatible = "st,stm32-fdcan";
|
compatible = "st,stm32-fdcan";
|
||||||
reg = <0x4000a400 0x400>, <0x4000ac00 0x350>;
|
reg = <0x4000a400 0x400>, <0x4000ac00 0x350>;
|
||||||
|
@ -783,12 +777,12 @@
|
||||||
interrupts = <39 0>, <40 0>;
|
interrupts = <39 0>, <40 0>;
|
||||||
interrupt-names = "LINE_0", "LINE_1";
|
interrupt-names = "LINE_0", "LINE_1";
|
||||||
clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000200>;
|
clocks = <&rcc STM32_CLOCK_BUS_APB1_2 0x00000200>;
|
||||||
status = "disabled";
|
bosch,mram-cfg = <0x0 28 8 3 3 0 3 3>;
|
||||||
sjw = <1>;
|
sjw = <1>;
|
||||||
sample-point = <875>;
|
sample-point = <875>;
|
||||||
sjw-data = <1>;
|
sjw-data = <1>;
|
||||||
sample-point-data = <875>;
|
sample-point-data = <875>;
|
||||||
};
|
status = "disabled";
|
||||||
};
|
};
|
||||||
|
|
||||||
ucpd1: ucpd@4000dc00 {
|
ucpd1: ucpd@4000dc00 {
|
||||||
|
|
|
@ -3,7 +3,7 @@ description: Specialization of Bosch m_can CAN-FD controller for Atmel SAM
|
||||||
compatible: "atmel,sam-can"
|
compatible: "atmel,sam-can"
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- name: can-fd-controller.yaml
|
- name: bosch,m_can-base.yaml
|
||||||
- name: pinctrl-device.yaml
|
- name: pinctrl-device.yaml
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
|
|
|
@ -3,7 +3,7 @@ description: Specialization of Bosch m_can CAN-FD controller for Atmel SAM0
|
||||||
compatible: "atmel,sam0-can"
|
compatible: "atmel,sam0-can"
|
||||||
|
|
||||||
include:
|
include:
|
||||||
- name: can-fd-controller.yaml
|
- name: bosch,m_can-base.yaml
|
||||||
- name: pinctrl-device.yaml
|
- name: pinctrl-device.yaml
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
description: Bosch M_CAN CAN-FD controller base
|
description: Bosch M_CAN CAN-FD controller base
|
||||||
|
|
||||||
compatible: "bosch,m_can-base"
|
include: [can-fd-controller.yaml]
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
bosch,mram-cfg:
|
bosch,mram-cfg:
|
||||||
|
|
|
@ -2,7 +2,7 @@ description: NXP LPC SoC series MCAN CAN-FD controller
|
||||||
|
|
||||||
compatible: "nxp,lpc-mcan"
|
compatible: "nxp,lpc-mcan"
|
||||||
|
|
||||||
include: [can-fd-controller.yaml, "bosch,m_can-base.yaml", pinctrl-device.yaml]
|
include: ["bosch,m_can-base.yaml", pinctrl-device.yaml]
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
reg:
|
reg:
|
||||||
|
|
|
@ -2,7 +2,7 @@ description: ST STM32 FDCAN CAN-FD controller
|
||||||
|
|
||||||
compatible: "st,stm32-fdcan"
|
compatible: "st,stm32-fdcan"
|
||||||
|
|
||||||
include: ["can-fd-controller.yaml", "pinctrl-device.yaml"]
|
include: ["bosch,m_can-base.yaml", "pinctrl-device.yaml"]
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
reg:
|
reg:
|
||||||
|
|
|
@ -2,7 +2,7 @@ description: ST STM32H7 series FDCAN CAN-FD controller
|
||||||
|
|
||||||
compatible: "st,stm32h7-fdcan"
|
compatible: "st,stm32h7-fdcan"
|
||||||
|
|
||||||
include: ["can-fd-controller.yaml", "pinctrl-device.yaml"]
|
include: ["bosch,m_can-base.yaml", "pinctrl-device.yaml"]
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
clocks:
|
clocks:
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue