可以参考下下面2个函数的处理:
uint8_t can_message_transmit(uint32_t can_periph, can_trasnmit_message_struct* transmit_message)
{
uint8_t mailbox_number = CAN_MAILBOX0;
uint8_t i = 0U;
uint8_t hit = 0U;
uint32_t canfd_en = 0U;
volatile uint32_t p_temp;
uint32_t reg_temp = 0U;
/* select one empty mailbox */
if(CAN_TSTAT_TME0 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME0)){
mailbox_number = CAN_MAILBOX0;
}else if(CAN_TSTAT_TME1 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME1)){
mailbox_number = CAN_MAILBOX1;
}else if(CAN_TSTAT_TME2 == (CAN_TSTAT(can_periph)&CAN_TSTAT_TME2)){
mailbox_number = CAN_MAILBOX2;
}else{
mailbox_number = CAN_NOMAILBOX;
}
/* return no mailbox empty */
if(CAN_NOMAILBOX == mailbox_number){
return CAN_NOMAILBOX;
}
CAN_TMI(can_periph, mailbox_number) &= CAN_TMI_TEN;
if(CAN_FF_STANDARD == transmit_message->tx_ff){
/* set transmit mailbox standard identifier */
CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_SFID(transmit_message->tx_sfid) | \
transmit_message->tx_ft);
}else{
/* set transmit mailbox extended identifier */
CAN_TMI(can_periph, mailbox_number) |= (uint32_t)(TMI_EFID(transmit_message->tx_efid) | \
transmit_message->tx_ff | \
transmit_message->tx_ft);
}
if(CAN_FDF_CLASSIC == transmit_message->fd_flag){
/* set the data length */
CAN_TMP(can_periph, mailbox_number) &= ~CAN_TMP_DLENC;
CAN_TMP(can_periph, mailbox_number) |= transmit_message->tx_dlen;
/* set the data */
CAN_TMDATA0(can_periph, mailbox_number) = TMDATA0_DB3(transmit_message->tx_data[3]) | \
TMDATA0_DB2(transmit_message->tx_data[2]) | \
TMDATA0_DB1(transmit_message->tx_data[1]) | \
TMDATA0_DB0(transmit_message->tx_data[0]);
CAN_TMDATA1(can_periph, mailbox_number) = TMDATA1_DB7(transmit_message->tx_data[7]) | \
TMDATA1_DB6(transmit_message->tx_data[6]) | \
TMDATA1_DB5(transmit_message->tx_data[5]) | \
TMDATA1_DB4(transmit_message->tx_data[4]);
}else{
canfd_en = CAN_FDCTL(can_periph) & CAN_FDCTL_FDEN;
/* check FD funciton has been enabled */
if(canfd_en){
if(transmit_message->tx_dlen <= 8U){
/* set the data length */
reg_temp |= transmit_message->tx_dlen;
}else{
/* data length greater than 8 */
for(i = 0U; i < 7U; i++){
if(transmit_message->tx_dlen == g_can_fdlength_table[i]){
hit = 1U;
break;
}
}
/* data length is valid */
if(1U == hit){
reg_temp |= 9U + i;
}else{
CAN_ERROR_HANDLE("dlen is invalid \r\n");
}
}
reg_temp |= (((uint32_t)transmit_message->fd_brs << 5U) | ((uint32_t)transmit_message->fd_esi << 4U) | ((uint32_t)transmit_message->fd_flag << 7U));
CAN_TMP(can_periph, mailbox_number) = reg_temp;
/* set the data */
i = transmit_message->tx_dlen / 4U;
/* data length is 5-7 need send 2 word */
if((1U==i) && (4U!=transmit_message->tx_dlen)){
i++;
}
p_temp = (uint32_t)transmit_message->tx_data;
if((0U==i)){
CAN_TMDATA0(can_periph, mailbox_number) = *(uint32_t *)p_temp;
}else{
for(; i>0U; i--){
CAN_TMDATA0(can_periph, mailbox_number) = *(uint32_t *)p_temp;
p_temp = ((uint32_t)((uint32_t)p_temp + 4U));
}
}
}else{
CAN_ERROR_HANDLE("CAN FD function disabled \r\n");
}
}
/* enable transmission */
CAN_TMI(can_periph, mailbox_number) |= CAN_TMI_TEN;
return mailbox_number;
}
void can_message_receive(uint32_t can_periph, uint8_t fifo_number, can_receive_message_struct* receive_message)
{
uint32_t canfd_en = 0U;
volatile uint32_t p_temp;
uint32_t data_temp;
uint8_t canfd_recv_cnt = 0U;
uint8_t i;
/* get the frame format */
receive_message->rx_ff = (uint8_t)(CAN_RFIFOMI_FF & CAN_RFIFOMI(can_periph, fifo_number));
if(CAN_FF_STANDARD == receive_message->rx_ff){
/* get standard identifier */
receive_message->rx_sfid = (uint32_t)(GET_RFIFOMI_SFID(CAN_RFIFOMI(can_periph, fifo_number)));
}else{
/* get extended identifier */
receive_message->rx_efid = (uint32_t)(GET_RFIFOMI_EFID(CAN_RFIFOMI(can_periph, fifo_number)));
}
/* get frame type */
receive_message->rx_ft = (uint8_t)(CAN_RFIFOMI_FT & CAN_RFIFOMI(can_periph, fifo_number));
/* filtering index */
receive_message->rx_fi = (uint8_t)(GET_RFIFOMP_FI(CAN_RFIFOMP(can_periph, fifo_number)));
receive_message->fd_flag = (uint8_t)(CAN_RFIFOMP_FDF & CAN_RFIFOMP(can_periph, fifo_number));
if(CAN_FDF_CLASSIC == receive_message->fd_flag){
/* get recevie data length */
receive_message->rx_dlen = (uint8_t)(GET_RFIFOMP_DLENC(CAN_RFIFOMP(can_periph, fifo_number)));
/* receive data */
receive_message->rx_data[0] = (uint8_t)(GET_RFIFOMDATA0_DB0(CAN_RFIFOMDATA0(can_periph, fifo_number)));
receive_message->rx_data[1] = (uint8_t)(GET_RFIFOMDATA0_DB1(CAN_RFIFOMDATA0(can_periph, fifo_number)));
receive_message->rx_data[2] = (uint8_t)(GET_RFIFOMDATA0_DB2(CAN_RFIFOMDATA0(can_periph, fifo_number)));
receive_message->rx_data[3] = (uint8_t)(GET_RFIFOMDATA0_DB3(CAN_RFIFOMDATA0(can_periph, fifo_number)));
receive_message->rx_data[4] = (uint8_t)(GET_RFIFOMDATA1_DB4(CAN_RFIFOMDATA1(can_periph, fifo_number)));
receive_message->rx_data[5] = (uint8_t)(GET_RFIFOMDATA1_DB5(CAN_RFIFOMDATA1(can_periph, fifo_number)));
receive_message->rx_data[6] = (uint8_t)(GET_RFIFOMDATA1_DB6(CAN_RFIFOMDATA1(can_periph, fifo_number)));
receive_message->rx_data[7] = (uint8_t)(GET_RFIFOMDATA1_DB7(CAN_RFIFOMDATA1(can_periph, fifo_number)));
}else{
canfd_en = CAN_FDCTL(can_periph) & CAN_FDCTL_FDEN;
/* check FD funciton has been enabled */
if(canfd_en){
/* get recevie data length */
canfd_recv_cnt = (uint8_t)(GET_RFIFOMP_DLENC(CAN_RFIFOMP(can_periph, fifo_number)));
if(canfd_recv_cnt <= 8U){
/* set the data length */
receive_message->rx_dlen = canfd_recv_cnt;
}else{
receive_message->rx_dlen = g_can_fdlength_table[canfd_recv_cnt - 9U];
}
receive_message->fd_brs = (uint8_t)((CAN_RFIFOMP(can_periph, fifo_number) & CAN_RFIFOMP_BRS) >> 5);
receive_message->fd_esi = (uint8_t)((CAN_RFIFOMP(can_periph, fifo_number) & CAN_RFIFOMP_ESI) >> 4);
/* get the data */
i = receive_message->rx_dlen / 4U;
/* data length is 5-7 need receive 2 word */
if((1U==i) && (4U!=receive_message->rx_dlen)){
i++;
}
p_temp = (uint32_t)(uint32_t)receive_message->rx_data;
if(0U==i){
data_temp = CAN_RFIFOMDATA0(can_periph, fifo_number);
*(uint32_t *)p_temp = data_temp;
}else{
/* get the data by reading from CAN_RFIFOMDATA0 register*/
for(; i>0U; i--){
data_temp = CAN_RFIFOMDATA0(can_periph, fifo_number);
*(uint32_t *)p_temp = data_temp;
p_temp = ((uint32_t)((uint32_t)p_temp + 4U));
}
}
}else{
CAN_ERROR_HANDLE("CAN FD function disabled \r\n");
}
}
/* release FIFO */
if(CAN_FIFO0 == fifo_number){
CAN_RFIFO0(can_periph) |= CAN_RFIFO0_RFD0;
}else{
CAN_RFIFO1(can_periph) |= CAN_RFIFO1_RFD1;
}
} |