It's very odd code is pretty much this. I guess I should have created one big structure for each and then arrayed them but more haste = less speed and duplicate code.
RAM buffers:
void *can_0_rx_variable_index[CAN_0_STD_MESSAGE_FILTER_NUM + CAN_0_EXD_MESSAGE_FILTER_NUM] ;
void *can_1_rx_variable_index[CAN_1_STD_MESSAGE_FILTER_NUM + CAN_1_EXD_MESSAGE_FILTER_NUM] ;
/********************************* RAM variables - buffers, FIFO's and filter elements ************************************/
CanMramXifde can_0_rx_exd_filter[CAN_0_EXD_MESSAGE_FILTER_NUM] ; // extended id filter elements
can_std_filter_element_t can_0_rx_std_filter[CAN_0_STD_MESSAGE_FILTER_NUM] ; // standard id filter elements
can_fifo_t can_0_rx_buffer[CAN_0_RX_FIFO_0_NUM] ; // receive buffer
can_tx_data_t can_0_tx_buffer[CAN_0_TX_FIFO_NUM] ; // transmit buffer
CanMramXifde can_1_rx_exd_filter[CAN_1_EXD_MESSAGE_FILTER_NUM] ; // extended id filter elements
can_std_filter_element_t can_1_rx_std_filter[CAN_1_STD_MESSAGE_FILTER_NUM] ; // standard id filter elements
can_fifo_t can_1_rx_buffer[CAN_1_RX_FIFO_0_NUM] ; // receive buffer
can_tx_data_t can_1_tx_buffer[CAN_1_TX_FIFO_NUM] ; // transmit buffer
setup:
void can_init(Can * instance )
{
uint8_t n = ret_can_port_n(instance) ;
connect_peripheral_to_clock((per_clock_channel_CAN0 + n), F_48MHz) ; // connect clock to CPU clock, bridge connection made in clock setup
instance->CCCR.bit.INIT = 1 ; // put the can peripheral into initialization mode
instance->CCCR.bit.CCE = 1 ; // enable writing of registers while in initialization mode
instance->CCCR.bit.TXP = 0 ; // Transmit pause enabled. The CAN pauses for two CAN bit times before starting the next transmission after itself has successfully transmitted a frame.
instance->CCCR.bit.DAR = 0 ; // Automatic retransmission of messages not transmitted successfully disabled.
instance->NBTP.bit.NBRP = (can_clock[n] / (can_baudrate[n] * 16U) ) - 1 ; //prescaler to obtain the arbitration field quantization clock max 511, a 1 is added by the hardware preventing division by 0.....
instance->TSCC.bit.TCP = 0xF ; // time stamp counter prescaler, actual value is +1 as dividing by "0" is - "silly".
//instance->TSCC.bit.TSS = 0x1 ; // enable this internal time stamp counter use system time counter instead
// Global filter configuration
instance->GFC.reg = 0x2 << 4 // Accept Non-matching Frames Standard: 0 = into FIFO 0, 1 = into FIFO 1, 2 or 3 reject
| 0x2 << 2 // Accept Non-matching Frames Extended: 0 = into FIFO 0, 1 = into FIFO 1, 2 or 3 reject
| 0x1 << 1 // Reject Remote Frames Standard : 0 = filter as normal, 1 = reject
| 0x1 << 0 ; // Reject Remote Frames Extended : 0 = filter as normal, 1 = reject
instance->MRCFG.bit.QOS = 0x3 ;
if (n == 0U)
{
// transmit FIFO0 settings
instance->TXBC.reg = (0xFFFF & ( (uint32_t) can_0_tx_buffer)) | CAN_TXBC_NDTB(CAN_0_TX_BUFFER_NUM) | CAN_TXBC_TFQS(CAN_0_TX_FIFO_NUM) ; // TFQM left out as left at "0"
// receive FIFO0 settings
instance->RXF0C.reg = CAN_RXF0C_F0SA( (uint32_t) (can_0_rx_buffer)) | CAN_RXF0C_F0S(CAN_0_RX_FIFO_0_NUM) ;
// rx standard filter settings
if (CAN_0_STD_MESSAGE_FILTER_NUM)
{
instance->SIDFC.reg = CAN_SIDFC_FLSSA( (uint32_t) can_0_rx_std_filter ) | CAN_SIDFC_LSS(CAN_0_STD_MESSAGE_FILTER_NUM) ;
}
// rx extended filter settings
if (CAN_0_EXD_MESSAGE_FILTER_NUM)
{
instance->XIDFC.reg = CAN_0_EXD_MESSAGE_FILTER_NUM << 16 | ( ( (uint32_t) can_0_rx_exd_filter ) & 0xFFFFUL ) ;
}
interrupt_enable(NVIC_INT_CAN0_CH) ;
}
if (n == 1U)
{
// transmit FIFO0 settings
instance->TXBC.reg = (0xFFFF & ( (uint32_t) can_1_tx_buffer)) | CAN_TXBC_NDTB(CAN_1_TX_BUFFER_NUM) | CAN_TXBC_TFQS(CAN_1_TX_FIFO_NUM) ; // TFQM left out as left at "0"
// receive FIFO0 settings
instance->RXF0C.reg = CAN_RXF0C_F0SA( (uint32_t) (can_1_rx_buffer)) | CAN_RXF0C_F0S(CAN_1_RX_FIFO_0_NUM) ;
// rx standard filter settings
if (CAN_1_STD_MESSAGE_FILTER_NUM)
{
instance->SIDFC.reg = CAN_1_STD_MESSAGE_FILTER_NUM << 16 | ( ( (uint32_t) can_1_rx_std_filter ) & 0xFFFFUL ) ;
}
if (CAN_1_EXD_MESSAGE_FILTER_NUM)
{
instance->XIDFC.reg = CAN_1_EXD_MESSAGE_FILTER_NUM << 16 | ( ( (uint32_t) can_1_rx_exd_filter ) & 0xFFFFUL ) ;
}
interrupt_enable(NVIC_INT_CAN1_CH) ;
}
// interrupts enable
instance->IE.bit.RF0NE = 0x1 ; // message received interrupt
instance->ILE.reg = 0x1 ; // enable interrupt line 0
instance->CCCR.bit.INIT = 0 ; // conclude can configuration
}
RX handlers
void CAN0_Handler_rx_by_id()
{
if (CAN0->IR.bit.RF0N)
{
static can_rx_data_t sorting_buffer ;
static uint8_t n ;
n = CAN0->RXF0S.bit.F0GI ; // make n the get index
CAN0->IR.reg = 0x1 << 0 ; // reset RF0N Rx FIFO 0 New Message
sorting_buffer.time_stamp = ret_rtc_us() ;
// copy data bytes only from RX fifo into holding variable that has the same layout as can_rx_data_t data types.
memcpy(&sorting_buffer , &can_0_rx_buffer[n].CAN_BUFFER_DATA , 8) ;
uint8_t exd_id_bit = can_0_rx_buffer[n].XTD ; // check for extended frame
CAN0->RXF0A.bit.F0AI = n ; // acknowledge data read so that get index increases
// memcpy from the sorting buffer variable to the destination variable.
if (exd_id_bit)
{
sorting_buffer.id = can_0_rx_buffer[n].ID ; // use exd_id_bit as shifting enabler to shift the std id down
memcpy(can_0_rx_variable_index[ can_0_rx_buffer[n].FIDX + CAN_0_STD_MESSAGE_FILTER_NUM - 1 ] , &sorting_buffer , 32 ) ;
}
else
{
sorting_buffer.id = can_0_rx_buffer[n].ID >> 18 ;
memcpy(can_0_rx_variable_index[ can_0_rx_buffer[n].FIDX ] , &sorting_buffer , 32 ) ;
}
}
}
void CAN1_Handler_rx_by_id()
{
if (CAN1->IR.bit.RF0N)
{
static can_rx_data_t sorting_buffer ;
static uint8_t can1_get_index ;
can1_get_index = CAN1->RXF0S.bit.F0GI ; // make n the get index
CAN1->IR.reg = 0x1 << 0 ; // reset RF0N Rx FIFO 0 New Message
sorting_buffer.time_stamp = ret_rtc_us() ;
// copy data bytes only from RX fifo into holding variable that has the same layout as can_rx_data_t data types.
memcpy(&sorting_buffer , &can_1_rx_buffer[can1_get_index].CAN_BUFFER_DATA , can_1_rx_buffer[can1_get_index].DLC) ;
uint8_t exd_id_bit = can_1_rx_buffer[can1_get_index].XTD ; // check for extended frame
CAN1->RXF0A.bit.F0AI = can1_get_index ; // acknowledge data read so that get index increases
// memcpy from the sorting buffer variable to the destination variable.
if (exd_id_bit)
{
sorting_buffer.id = can_1_rx_buffer[can1_get_index].ID ;
memcpy(can_1_rx_variable_index[ can_1_rx_buffer[can1_get_index].FIDX + CAN_1_STD_MESSAGE_FILTER_NUM - 1 ] , &sorting_buffer , 32 ) ;
}
else
{
sorting_buffer.id = can_1_rx_buffer[can1_get_index].ID >> 18 ; // use exd_id_bit as shifting enabler to shift the std id down
memcpy(can_1_rx_variable_index[ can_1_rx_buffer[can1_get_index].FIDX ] , &sorting_buffer , 32 ) ;
}
}
}
[code]
RX filters setup
[code]
void can_std_filter_setup(Can * instance , uint16_t id , uint8_t filter_element_n , void * variable )
{
uint8_t n = ret_can_port_n(instance) ;
if (n == 0)
{
can_0_rx_variable_index[filter_element_n] = variable ; // add the address of the allocated variable to the to the array that points to variables by ID/ filter element number
// see MTTCAN 2.4.5
can_0_rx_std_filter[filter_element_n].bit.SFEC = 0x1 ; // store in FIFO 0
can_0_rx_std_filter[filter_element_n].bit.SFID1 = id ; // message id
can_0_rx_std_filter[filter_element_n].bit.SFID2 = id ; // message id
can_0_rx_std_filter[filter_element_n].bit.SFT = 0x1 ; // dual id filter
}
if (n == 1)
{
can_1_rx_variable_index[filter_element_n] = variable ; // add the address of the allocated variable to the to the array that points to variables by ID/ filter element number
// see MTTCAN 2.4.5
can_1_rx_std_filter[filter_element_n].bit.SFEC = 0x1 ; // store in FIFO 0
can_1_rx_std_filter[filter_element_n].bit.SFID1 = id ; // message id
can_1_rx_std_filter[filter_element_n].bit.SFID2 = id ; // message id
can_1_rx_std_filter[filter_element_n].bit.SFT = 0x1 ; // dual id filter
}
}
void can_exd_filter_setup(Can * instance , uint32_t id , uint8_t filter_element_n , void * variable )
{
uint8_t n = ret_can_port_n(instance) ;
if (n == 0)
{
can_0_rx_variable_index[filter_element_n + CAN_0_STD_MESSAGE_FILTER_NUM - 1U] = variable ; // add the address of the allocated variable to the to the array that points to variables by ID/ filter element number
// see MTTCAN
can_0_rx_exd_filter[filter_element_n].XIDFE_0.bit.EFEC = 0x1 ;
can_0_rx_exd_filter[filter_element_n].XIDFE_0.bit.EFID1 = id ;
can_0_rx_exd_filter[filter_element_n].XIDFE_1.bit.EFT = 0x1 ;
can_0_rx_exd_filter[filter_element_n].XIDFE_1.bit.EFID2 = id ;
}
if (n == 1)
{
can_1_rx_variable_index[filter_element_n + CAN_1_STD_MESSAGE_FILTER_NUM - 1U] = variable ; // add the address of the allocated variable to the to the array that points to variables by ID/ filter element number
// see MTTCAN
can_1_rx_exd_filter[filter_element_n].XIDFE_0.bit.EFEC = 0x1 ;
can_1_rx_exd_filter[filter_element_n].XIDFE_0.bit.EFID1 = id ;
can_1_rx_exd_filter[filter_element_n].XIDFE_1.bit.EFT = 0x1 ;
can_1_rx_exd_filter[filter_element_n].XIDFE_1.bit.EFID2 = id ;
}
}