Electronics > Microcontrollers
SAMC MCAN CANbus controller message RAM management
Simon:
I'm starting to write code for the CAN bus controller on the SAMC, this is a bosch MCAN controller used under licence.
I have one message from slot 0 transmitting but other slots are a challenge. I have tried to check that my memory address math is correct and that I am pointing to the right location in RAM memory. I have noticed that the debugger mentions other variables or even functions when I look at the location.
Is it that if I simply point to the address in the code without claiming this space as a variable that the RAM my get used by something else as the compiler is unaware of the dual use?
Am I safer creating say a structure for each buffer to be mapped to in RAM in a similar way to how the registers are mapped in the chip header files so that it's clear that this space is off limits to other stuff?
ataradov:
--- Quote from: Simon on September 28, 2023, 09:15:31 am ---Is it that if I simply point to the address in the code without claiming this space as a variable that the RAM my get used by something else as the compiler is unaware of the dual use?
--- End quote ---
Yes, of course. How would compiler know?
--- Quote from: Simon on September 28, 2023, 09:15:31 am ---Am I safer creating say a structure for each
--- End quote ---
This is the only correct way of doing it. Apart of reserving the memory in a linker script. But that's just extra work for no benefit.
Simon:
I see, well this is the first time I work with something where I am using raw RAM like registers.
Rudolph Riedel:
Here, this is what I am using for a while now:
--- Code: ---#define CAN0_TX_BUFFER_NUM 4
#define CAN0_RX_FIFO_NUM 32
#define CAN0_ELEMENT_DATA_SIZE 64
#define CAN0_STANDARD_ID_FILTER_NUM 4
#define CAN0_EXTENDED_ID_FILTER_NUM 4
struct can_tx_element
{
volatile CAN_TXBE_0_Type T0;
volatile CAN_TXBE_1_Type T1;
uint8_t data[CAN0_ELEMENT_DATA_SIZE];
} __attribute__((__aligned__(4)));
struct can_rx_element
{
volatile CAN_RXBE_0_Type R0;
volatile CAN_RXBE_1_Type R1;
uint8_t data[CAN0_ELEMENT_DATA_SIZE];
} __attribute__((__aligned__(4)));
struct can_rx_fifo_element
{
volatile CAN_RXF0E_0_Type R0;
volatile CAN_RXF0E_1_Type R1;
uint8_t data[CAN0_ELEMENT_DATA_SIZE];
} __attribute__((__aligned__(4)));
struct can_standard_message_filter_element
{
CAN_SIDFE_0_Type S0;
} __attribute__((__aligned__(4)));
struct can_extended_message_filter_element
{
CAN_XIDFE_0_Type F0;
CAN_XIDFE_1_Type F1;
} __attribute__((__aligned__(4)));
static struct can_tx_element can0_tx_buffer[CAN0_TX_BUFFER_NUM];
static struct can_standard_message_filter_element can0_standard_id_filter[CAN0_STANDARD_ID_FILTER_NUM];
static struct can_rx_fifo_element can0_rx_fifo[CAN0_RX_FIFO_NUM];
static struct can_extended_message_filter_element can0_extended_id_filter[CAN0_EXTENDED_ID_FILTER_NUM];
--- End code ---
And then I have this in my setup function:
--- Code: --- if (can_channel == CAN0)
{
/* TX Buffer Configuration */
can_channel->TXBC.reg = CAN_TXBC_TBSA((uint32_t) can0_tx_buffer) | CAN_TXBC_NDTB(CAN0_TX_BUFFER_NUM);
/* RX FIFO Configuration */
can_channel->RXF0C.reg = CAN_RXF0C_F0SA((uint32_t) can0_rx_fifo) | CAN_RXF0C_F0S(CAN0_RX_FIFO_NUM) | CAN_RXF0C_F0OM; // FIFO 0 overwrite mode
/* ID filter buffer configuration */
can_channel->SIDFC.reg = CAN_SIDFC_FLSSA((uint32_t) can0_standard_id_filter) | CAN_SIDFC_LSS(CAN0_STANDARD_ID_FILTER_NUM);
/* ID filter buffer configuration */
can_channel->XIDFC.reg = CAN_XIDFC_FLESA((uint32_t) can0_extended_id_filter) | CAN_XIDFC_LSE(CAN0_EXTENDED_ID_FILTER_NUM);
}
--- End code ---
Simon:
Thank you. I'll take a look, I tried something similar but ended up with blank messages so I have probably made a mess of the pointers.
one thing I have found is that one a transmission is triggered is just keeps going. I start it with the bit in the TXBAR register.
Navigation
[0] Message Index
[#] Next page
Go to full version