AtsamC21E15A Canbus Normal Mode Problem

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Hi Folks,

 

Im trying to write Can-Bus Normal Mode operational code for AtsamC21E15A, now i created Atmel Start code that contains basicly USART and Canbus peripherals (Atmel Start CanBus configuration picture edited below maybe configuration wrong.)

 

Simply my goal, receive and transmit certain data on Can-Bus. My setup basicly, custom board which contains atsamc21e15a mcu, canbus tranciever and also CanH and CanL line connected Microchip Can Bus Analyzer tool for Listening and Normal mode purposes.

 

My first attempt with this setup was simple loopback mode working in code.

This code running on External LoopBack Mode in Atsamc21 family datasheet contain this External LoopBack mode page 605 (Related Atmel Start generated code is below  maybe i wrote wrong) , also Can-Bus Analyzer was in listen mode and/or normal mode( In Microchip Can Bus Analyzer Tool's Gui, we can set Listen Mode and Normal Mode, my case both of them work with my loop back mode but one difference is ACK bit existance).  

 

In Can-bus analyzer Gui, i saw message which send from my atmel start generated code (mcu) and also in code i wrote message on Usart for validation, and also i saw the message on Can-H line with an Oscilloscope , all working good.

****************************************ooooo***********************************************

 

 

But i wanna work with Normal Can-Bus mode communication(related code is below)  but not working,  instead of , i saw this signal on Oscilloscope(image is below.). What was wrong, i dont understand.

Below is Loop back mode code:

void CAN_example(void)
{
	struct can_message msg;
	struct can_filter  filter;
	uint8_t            send_data[4];
	send_data[0] = 0x00;
	send_data[1] = 0x01;
	send_data[2] = 0x02;
	send_data[3] = 0x03;

	msg.id   = 0x45A;
	msg.type = CAN_TYPE_DATA;
	msg.data = send_data;
	msg.len  = 4;
	msg.fmt  = CAN_FMT_STDID;
	can_async_register_callback(&CAN, CAN_ASYNC_TX_CB, (FUNC_PTR)CAN_tx_callback);

	can_async_enable(&CAN);

	/**
	 * CAN_tx_callback callback should be invoked after call
	 * can_async_write, and remote device should recieve message with ID=0x45A
	 */
	can_async_write(&CAN, &msg);

	/**
	 * CAN_rx_callback callback should be invoked after call
	 * can_async_set_filter and remote device send CAN Message with the same
	 * content as the filter.
	 */
	can_async_register_callback(&CAN, CAN_ASYNC_RX_CB, (FUNC_PTR)CAN_rx_callback);
	filter.id   = 0x469;
	filter.mask = 0;
	can_async_set_filter(&CAN, 0, CAN_FMT_STDID, &filter);

}

main:

#include <atmel_start.h>

int main(void)
{
	/* Initializes MCU, drivers and middleware */
	atmel_start_init();

	/* Replace with your application code */
	while (1)
	{
		CAN_example();
		delay_ms(1024);

	}
}

hpl_can.c:

/**
 * \brief Initialize CAN.
 */
int32_t _can_async_init(struct _can_async_device *const dev, void *const hw)
{
	dev->hw = hw;
	hri_can_set_CCCR_INIT_bit(dev->hw);
	while (hri_can_get_CCCR_INIT_bit(dev->hw) == 0)
		;
	hri_can_set_CCCR_CCE_bit(dev->hw);

#ifdef CONF_CAN0_ENABLED
	if (hw == CAN0) {
		_can0_dev    = dev;
		dev->context = (void *)&_can0_context;
		hri_can_set_CCCR_reg(dev->hw, CONF_CAN0_CCCR_REG);
		hri_can_write_MRCFG_reg(dev->hw, CONF_CAN0_MRCFG_REG);
		hri_can_write_NBTP_reg(dev->hw, CONF_CAN0_BTP_REG);
		hri_can_write_DBTP_reg(dev->hw, CONF_CAN0_DBTP_REG);
		hri_can_write_RXF0C_reg(dev->hw, CONF_CAN0_RXF0C_REG | CAN_RXF0C_F0SA((uint32_t)can0_rx_fifo));
		hri_can_write_RXESC_reg(dev->hw, CONF_CAN0_RXESC_REG);
		hri_can_write_TXESC_reg(dev->hw, CONF_CAN0_TXESC_REG);
		hri_can_write_TXBC_reg(dev->hw, CONF_CAN0_TXBC_REG | CAN_TXBC_TBSA((uint32_t)can0_tx_fifo));
		hri_can_write_TXEFC_reg(dev->hw, CONF_CAN0_TXEFC_REG | CAN_TXEFC_EFSA((uint32_t)can0_tx_event_fifo));
		hri_can_write_GFC_reg(dev->hw, CONF_CAN0_GFC_REG);
		hri_can_write_SIDFC_reg(dev->hw, CONF_CAN0_SIDFC_REG | CAN_SIDFC_FLSSA((uint32_t)can0_rx_std_filter));
		hri_can_write_XIDFC_reg(dev->hw, CONF_CAN0_XIDFC_REG | CAN_XIDFC_FLESA((uint32_t)can0_rx_ext_filter));
		hri_can_write_XIDAM_reg(dev->hw, CONF_CAN0_XIDAM_REG);

        hri_can_set_CCCR_TEST_bit(dev->hw); // Self Test for LoopBack.
        hri_can_set_TEST_LBCK_bit(dev->hw); // Self Test for LoopBack.

		NVIC_DisableIRQ(CAN0_IRQn);
		NVIC_ClearPendingIRQ(CAN0_IRQn);
		NVIC_EnableIRQ(CAN0_IRQn);
		hri_can_write_ILE_reg(dev->hw, CAN_ILE_EINT0);
	}
#endif

#ifdef CONF_CAN1_ENABLED
	if (hw == CAN1) {
		_can1_dev    = dev;
		dev->context = (void *)&_can1_context;
		hri_can_set_CCCR_reg(dev->hw, CONF_CAN1_CCCR_REG);
		hri_can_write_MRCFG_reg(dev->hw, CONF_CAN1_MRCFG_REG);
		hri_can_write_NBTP_reg(dev->hw, CONF_CAN1_BTP_REG);
		hri_can_write_DBTP_reg(dev->hw, CONF_CAN1_DBTP_REG);
		hri_can_write_RXF0C_reg(dev->hw, CONF_CAN1_RXF0C_REG | CAN_RXF0C_F0SA((uint32_t)can1_rx_fifo));
		hri_can_write_RXESC_reg(dev->hw, CONF_CAN1_RXESC_REG);
		hri_can_write_TXESC_reg(dev->hw, CONF_CAN1_TXESC_REG);
		hri_can_write_TXBC_reg(dev->hw, CONF_CAN1_TXBC_REG | CAN_TXBC_TBSA((uint32_t)can1_tx_fifo));
		hri_can_write_TXEFC_reg(dev->hw, CONF_CAN1_TXEFC_REG | CAN_TXEFC_EFSA((uint32_t)can1_tx_event_fifo));
		hri_can_write_GFC_reg(dev->hw, CONF_CAN1_GFC_REG);
		hri_can_write_SIDFC_reg(dev->hw, CONF_CAN1_SIDFC_REG | CAN_SIDFC_FLSSA((uint32_t)can1_rx_std_filter));
		hri_can_write_XIDFC_reg(dev->hw, CONF_CAN1_XIDFC_REG | CAN_XIDFC_FLESA((uint32_t)can1_rx_ext_filter));
		hri_can_write_XIDAM_reg(dev->hw, CONF_CAN1_XIDAM_REG);

		NVIC_DisableIRQ(CAN1_IRQn);
		NVIC_ClearPendingIRQ(CAN1_IRQn);
		NVIC_EnableIRQ(CAN1_IRQn);
		hri_can_write_ILE_reg(dev->hw, CAN_ILE_EINT0);
	}
#endif

	/* Disable CCE to prevent Configuration Change */
	hri_can_clear_CCCR_CCE_bit(dev->hw);
	hri_can_clear_CCCR_INIT_bit(dev->hw);
	while (hri_can_get_CCCR_INIT_bit(dev->hw)) {
	};

	return ERR_NONE;
}

Note:: Normal mode operation icode not contain 2 line at below in hpl_can.c . This 2 line is for External Loopback. Normal mode and External loopback codes are the same but 1 difference, i mention here. 

        hri_can_set_CCCR_TEST_bit(dev->hw); // Self Test for LoopBack.
        hri_can_set_TEST_LBCK_bit(dev->hw); // Self Test for LoopBack.

Below, i added canbus tool picture when i  run this Normal Mode code, configuration 50 kbit same as Atmel Start generated code. Cna bus Analayzer picture and above Oscilloscope picture is the same, these are Normal mode outputs taken by me.

Note: when i change to listen mode to normal mode, i didnt see anything in Gui but in  Oscilloscope same picture seems.

 

This topic has a solution.
Last Edited: Sun. Apr 18, 2021 - 08:07 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This oscillascope view is an Error Frame??

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

Searching in google this oscillascope image maybe an Error Passive frame format. I guess.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Im usiing QFN package mcu and i miss RX pin of MCU not connect to pcb properly. 

 

Whole problem because of this.