Robobo
Use case #1

In this use case, CAN0 mailbox 0 works in PRODUCER mode, and CAN1 mailbox 0 works in CONSUMER mode. While CAN1 mailbox 0 receives a data frame from the bus, an interrupt is triggered.

Setup steps

Prerequisites

  • Power Management Controller driver
  • CAN transceiver driver

Example code

Add to application C-file:

can_mb_conf_t can0_mailbox;
can_mb_conf_t can1_mailbox;
volatile uint32_t g_ul_recv_status = 0;
void CAN1_Handler(void)
{
uint32_t ul_status;
ul_status = can_mailbox_get_status(CAN1, 0);
if ((ul_status & CAN_MSR_MRDY) == CAN_MSR_MRDY) {
can1_mailbox.ul_mb_idx = 0;
can1_mailbox.ul_status = ul_status;
can_mailbox_read(CAN1, &can1_mailbox);
g_ul_recv_status = 1;
}
}
can_init(CAN0, ul_sysclk, CAN_BPS_1000K);
can_init(CAN1, ul_sysclk, CAN_BPS_1000K);
can_reset_all_mailbox(CAN0);
can_reset_all_mailbox(CAN1);
can0_mailbox.ul_mb_idx = 0;
can0_mailbox.uc_obj_type = CAN_MB_PRODUCER_MODE;
can0_mailbox.ul_id_msk = 0;
can0_mailbox.ul_id = CAN_MID_MIDvA(0x0b);
can_mailbox_init(CAN0, &can0_mailbox);
can0_mailbox.ul_datal = 0x11223344;
can0_mailbox.ul_datah = 0x44332211;
can0_mailbox.uc_length = 8;
can_mailbox_write(CAN0, &can0_mailbox);
can1_mailbox.ul_mb_idx = 0;
can1_mailbox.uc_obj_type = CAN_MB_CONSUMER_MODE;
can1_mailbox.uc_tx_prio = 15;
can1_mailbox.ul_id = CAN_MID_MIDvA(0x0b);
can_mailbox_init(CAN1, &can1_mailbox);
can_enable_interrupt(CAN1, CAN_IER_MB0);
NVIC_EnableIRQ(CAN1_IRQn);

Workflow

  1. Define the CAN0 and CAN1 Transfer mailbox structure:
  2. Define the receive flag that is changed in CAN1 ISR handler:
    • volatile uint32_t g_ul_recv_status = 0;
  3. Define the CAN1 ISR handler in the application:
    • void CAN1_Handler(void);
  4. In CAN1_Handler(), get CAN1 mailbox 0 status:
    • ul_status = can_mailbox_get_status(CAN1, 0);
  5. In CAN1_Handler(), check whether the mailbox 0 has received a data frame:
    • if ((ul_status & CAN_MSR_MRDY) == CAN_MSR_MRDY) {
      can1_mailbox.ul_mb_idx = 0;
      can1_mailbox.ul_status = ul_status;
      can_mailbox_read(CAN1, &can1_mailbox);
      g_ul_recv_status = 1;
      }
  6. In CAN1_Handler(), if mailbox 0 is ready, read the received data from CAN1 mailbox 0:
    • can1_mailbox.ul_mb_idx = 0;
      can1_mailbox.ul_status = ul_status;
      can_mailbox_read(CAN1, &can1_mailbox);
  7. In CAN1_Handler(), if mailbox 0 is ready, set up the receive flag:
    • g_ul_recv_status = 1;
  8. Enable the module clock for CAN0 and CAN1:
  9. Initialize CAN0 and CAN1, baudrate is 1Mb/s:
  10. Reset all CAN0 and CAN1 mailboxes:
    • can_reset_all_mailbox(CAN0);
      can_reset_all_mailbox(CAN1);
  11. Initialize CAN0 mailbox 0 as PRODUCER:
    • can0_mailbox.ul_mb_idx = 0;
      can0_mailbox.uc_obj_type = CAN_MB_PRODUCER_MODE;
      can0_mailbox.ul_id_msk = 0;
      can0_mailbox.ul_id = CAN_MID_MIDvA(0x0b);
      can_mailbox_init(CAN0, &can0_mailbox);
  12. Prepare the response information when it receives a remote frame:
    • can0_mailbox.ul_datal = 0x11223344;
      can0_mailbox.ul_datah = 0x44332211;
      can0_mailbox.uc_length = 8;
      can_mailbox_write(CAN0, &can0_mailbox);
  13. Initialize CAN1 mailbox 0 as CONSUMER:
  14. Enable the CAN1 mailbox 0 interrupt:

Usage steps

Example code

can_global_send_transfer_cmd(CAN0, CAN_TCR_MB0);
can_global_send_transfer_cmd(CAN1, CAN_TCR_MB0);
while (!g_ul_recv_status) {
}

Workflow

  1. Enable CAN0 mailbox 0 to receive remote frame and respond it:
  2. Enable CAN1 mailbox 0 to send out a remote frame and then receive data frame from bus:
  3. Wait for the communication to be completed.
    • while (!g_ul_recv_status) {
      }