I have tried to call SCB_CleanDCache_by_Addr
but it doesn’t alter the situation.
This driver code is supplied by Atmel from Atmel Start.
/**
* \brief Write a CAN message
*/
int32_t _can_async_write(struct _can_async_device *const dev, struct can_message *msg)
{
struct _can_tx_fifo_entry *f = NULL;
hri_mcan_txfqs_reg_t put_index;
if (hri_mcan_get_TXFQS_TFQF_bit(dev->hw)) {
return ERR_NO_RESOURCE;
}
put_index = hri_mcan_read_TXFQS_TFQPI_bf(dev->hw);
PUT_INDEX = put_index;
#ifdef CONF_CAN0_ENABLED
if (dev->hw == MCAN0) {
f = (struct _can_tx_fifo_entry *)(can0_tx_fifo + put_index * CONF_CAN0_TBDS);
}
#endif
#ifdef CONF_CAN1_ENABLED
if (dev->hw == MCAN1) {
f = (struct _can_tx_fifo_entry *)(can1_tx_fifo + put_index * CONF_CAN1_TBDS);
}
#endif
if (f == NULL) {
return ERR_NO_RESOURCE;
}
F = f;
f->T0.bit.RTR = (msg->type == CAN_TYPE_REMOTE) ? 1 : 0;
if (msg->fmt == CAN_FMT_EXTID) {
f->T0.val = msg->id;
f->T0.bit.XTD = 1;
} else {
/* A standard identifier is stored into ID[28:18] */
f->T0.val = msg->id << 18;
}
if (msg->len <= 8) {
f->T1.bit.DLC = msg->len;
} else if (msg->len <= 12) {
f->T1.bit.DLC = 0x9;
} else if (msg->len <= 16) {
f->T1.bit.DLC = 0xA;
} else if (msg->len <= 20) {
f->T1.bit.DLC = 0xB;
} else if (msg->len <= 24) {
f->T1.bit.DLC = 0xC;
} else if (msg->len <= 32) {
f->T1.bit.DLC = 0xD;
} else if (msg->len <= 48) {
f->T1.bit.DLC = 0xE;
} else if (msg->len <= 64) {
f->T1.bit.DLC = 0xF;
}
f->T1.bit.FDF = hri_mcan_get_CCCR_FDOE_bit(dev->hw);
f->T1.bit.BRS = hri_mcan_get_CCCR_BRSE_bit(dev->hw);
memcpy(f->data, msg->data, msg->len);
SCB_CleanDCache_by_Addr ( (uint32_t*)f, sizeof(struct _can_tx_fifo_entry) ); // <<== Flushing the cache area that contains struct _can_tx_fifo_entry
hri_mcan_write_TXBAR_reg(dev->hw, 1 << hri_mcan_read_TXFQS_TFQPI_bf(dev->hw));
return ERR_NONE;
}
I have stepped a lot through the driver code… and I can see struct _can_tx_fifo_entry being filled properly.
Could I been using the function SCB_CleanDCache_by_Addr in the wrong way?
f is address of struct _can_tx_fifo_entry.
If I disable the cache by calling SCB_DisableDCache() it gives the same result.
I think FreeRTOS does not enable the cache. true?
Being that the case if it is a Cache issue why does it work outside FreeRTOS and not inside?