Как отладить шину CAN в контроллере SAM4e? - PullRequest
0 голосов
/ 27 января 2020

Я только начал программировать микроконтроллер SAM4e для CAN, но столкнулся с проблемой. Я реализовал USB_serial comm для отладки процесса CAN, но не сильно помог. Конфигурация CAN работает нормально. Это также показывает, что данные передаются, но на другом контроллере данные не принимаются. Я использую контроллер ATSAM4e8e и трансивер TJA1050.

#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);
    }

}
...