0

I've just started programming SAM4e microcontroller for CAN but facing a problem. I've implemented USB_serial comm to debug the CAN process but not helping much. The CAN configuration is working fine. It also showing data is being transmitted but on the other controller data is not getting received. I'm using ATSAM4e8e controller and TJA1050 transreceiver.

#include "asf.h"
#include "stdio_usb.h"
#include "pmc.h"
#include "conf_clock.h"
#include "user_board.h"
#include "sam4e8e.h"

#define STRING_EOL    "\r"
#define STRING_HEADER "-- CAN Example --\r\n" \
                        "-- ATSAM4E --\r\n" \
                        "-- Compiled: "__DATE__" "__TIME__" --"STRING_EOL

#define CAN_COMM_RXMB_ID    0
#define CAN_COMM_TXMB_ID    1
#define CAN_TRANSFER_ID     7
#define CAN_TX_PRIO         15
#define CAN_MSG_DUMMY_DATA  0x55AAAA55u

/** CAN frame max data length */
#define MAX_CAN_FRAME_DATA_LEN      8

/** Transfer mailbox structure */
can_mb_conf_t tx_mailbox, rx_mailbox;

/** Receive status */
volatile uint32_t g_ul_recv_status = 0;

/**
 * \brief Default interrupt handler for CAN 1.
 */
void CAN1_Handler(void)
{
    uint32_t ul_status;

    ul_status = can_mailbox_get_status(CAN1, 0);
    if (ul_status & CAN_MSR_MRDY) {
        rx_mailbox.ul_status = ul_status;
        can_mailbox_read(CAN1, &rx_mailbox);
        puts("Got CAN message, press 'r' to display\r");
        g_ul_recv_status = 1;
    }
}

/**
 * \brief Decode CAN messages.
 *
 *  \param p_mailbox Pointer to CAN Mailbox structure.
 */
static void decode_can_msg(can_mb_conf_t *p_mailbox)
{
    if (p_mailbox->ul_datal != CAN_MSG_DUMMY_DATA) {
        puts("Wrong message header\r");
    } else {
        printf("%d\r\n", (int)p_mailbox->ul_datah);
    }
}

/**
 * \brief Reset mailbox configure structure.
 *
 *  \param p_mailbox Pointer to mailbox configure structure.
 */
static void reset_mailbox_conf(can_mb_conf_t *p_mailbox)
{
    p_mailbox->ul_mb_idx = 0;
    p_mailbox->uc_obj_type = 0;
    p_mailbox->uc_id_ver = 0;
    p_mailbox->uc_length = 0;
    p_mailbox->uc_tx_prio = 0;
    p_mailbox->ul_status = 0;
    p_mailbox->ul_id_msk = 0;
    p_mailbox->ul_id = 0;
    p_mailbox->ul_fid = 0;
    p_mailbox->ul_datal = 0;
    p_mailbox->ul_datah = 0;
}

/**
 *  Configure UART for debug message output.
 */
static void configure_console(void)
{
        /* Configure console UART. */
    sysclk_enable_peripheral_clock(ID_UDP);
    stdio_usb_init();

}

/**
 *  \brief can_example application entry point.
 *
 *  \return Unused (ANSI-C compatibility).
 */
int main(void)
{
    uint32_t ul_sysclk, cnt = 0;
    char uc_key;

    /* Initialize the SAM system. */
    sysclk_init();
    board_init();

    /* Configure UART for debug message output. */
    configure_console();

    /* Output example information. */
    puts(STRING_HEADER);

    /* Enable CAN1 clock. */
    pmc_enable_periph_clk(ID_CAN1);

    ul_sysclk = sysclk_get_cpu_hz();
    if (can_init(CAN1, ul_sysclk, CAN_BPS_1000K)) {
        puts("CAN initialization is completed." STRING_EOL);

        /* Disable all CAN1 interrupts. */
        can_disable_interrupt(CAN1, CAN_DISABLE_ALL_INTERRUPT_MASK);
        can_reset_all_mailbox(CAN1);

        /* Init CAN1 Mailbox 0 to Reception Mailbox. */
        reset_mailbox_conf(&rx_mailbox);
        rx_mailbox.ul_mb_idx = CAN_COMM_RXMB_ID;
        rx_mailbox.uc_obj_type = CAN_MB_RX_MODE;
        rx_mailbox.ul_id_msk = CAN_MAM_MIDvA_Msk | CAN_MAM_MIDvB_Msk;
        rx_mailbox.ul_id = CAN_MID_MIDvA(CAN_TRANSFER_ID);
        can_mailbox_init(CAN1, &rx_mailbox);

        /* Init CAN1 Mailbox 1 to Transmit Mailbox. */
        reset_mailbox_conf(&tx_mailbox);
        tx_mailbox.ul_mb_idx = CAN_COMM_TXMB_ID;
        tx_mailbox.uc_obj_type = CAN_MB_TX_MODE;
        tx_mailbox.uc_tx_prio = CAN_TX_PRIO;
        tx_mailbox.uc_id_ver = 0;
        tx_mailbox.ul_id_msk = 0;
        can_mailbox_init(CAN1, &tx_mailbox);

        /* Write transmit information into mailbox. */
        tx_mailbox.ul_id = CAN_MID_MIDvA(CAN_TRANSFER_ID);
        tx_mailbox.ul_datal = CAN_MSG_DUMMY_DATA;
        tx_mailbox.uc_length = MAX_CAN_FRAME_DATA_LEN;

        /* Enable CAN1 mailbox interrupt. */
        can_enable_interrupt(CAN1, 1 << CAN_COMM_RXMB_ID);

        /* Configure and enable interrupt of CAN1. */
        NVIC_EnableIRQ(CAN1_IRQn);

        puts("\tt: Perform CAN Transmisson \r");

        while (1) {
            scanf("%c", &uc_key);

            switch (uc_key) {
            case 'R':
            case 'r':
                if (!g_ul_recv_status) {
                    puts("No CAN message\r");
                } else {
                    g_ul_recv_status = 0;
                    decode_can_msg(&rx_mailbox);
                    puts("CAN data decoded\n");
                }
                break;

            case 'T':
            case 't':
                if (can_get_status(CAN1) & CAN_SR_TBSY) {
                    puts("Transmission is busy\r");
                } else {
                    tx_mailbox.ul_datah = cnt++;
                    can_mailbox_write(CAN1, &tx_mailbox);
                    /* Send out the information in the mailbox. */
                    can_global_send_transfer_cmd(CAN1, CAN_TCR_MB1);
                    puts("Message is sent\n");
                }
                break;

            default:
                puts("Unknown input\r");
                break;
            }
        }
    } else {
        puts("CAN initialization (sync) ERROR" STRING_EOL);
    }

}
  • Is the transmitting node receiving the data? – stark Jan 27 '20 at 12:15
  • 1
    "The CAN configuration is working fine" How do you know? Is there any traffic coming out on the wires? Measure with scope or a CAN analyser/listener. – Lundin Jan 27 '20 at 14:30
  • As far I'm not getting any error no from API's which I'm calling for configuration. I'm not getting any traffic. I don't have scope but can I use Multimeter. I'll check configuration again. – Saurabh Sakhare Jan 28 '20 at 04:50
  • Thank you for support. There was issue in my hardware connections. – Saurabh Sakhare Jan 28 '20 at 09:05
  • To do this project you need a scope and/or a CAN listener, preferably both. A multimeter will only let you check the physical basics: cables & connectors ok, 60 ohm impedance, is there voltage present. But you won't be able to spot error frames, no ack errors etc, let alone validate the actual data & bus load. – Lundin Jan 28 '20 at 10:35
  • Yeah. Understood.. As temporary I used LED to debug if line is getting signals or not ;-) Thank you. – Saurabh Sakhare Jan 30 '20 at 11:18

0 Answers0