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