CAN Bus Library for STM32F103

Can someone help me port this library?
Akash
Posts: 1
Joined: Tue Sep 12, 2017 6:35 am

Re: CAN Bus Library for STM32F103

Post by Akash » Tue Sep 12, 2017 6:55 am

Hello friends, I am using olimexino STM32 board with CAN bus ANalyzer. From HardwareCAN library is suitable for sending message but we can not filter message by list,it can only read all message. for doing filter list, what should I need to change below??

Code: Select all

CAN_STATUS can_filter(CAN_Port* CANx, uint8 filter_idx, CAN_FIFO fifo, CAN_FILTER_SCALE scale, CAN_FILTER_MODE mode, uint32 fr1, uint32 fr2)
{
	uint32 mask = ((uint32)0x00000001) << filter_idx;

	CANx->FMR |= CAN_FMR_FINIT;		// Initialization mode for the filter
	CANx->FA1R &= ~mask;			// Deactivation filter


	if (scale == CAN_FILTER_32BIT)
		CANx->FS1R |= mask;
	else
		CANx->FS1R &= ~mask;

	CANx->sFilterRegister[filter_idx].FR1 = fr1;
	CANx->sFilterRegister[filter_idx].FR2 = fr2;

	if (mode == CAN_FILTER_MASK)
		CANx->FM1R &= ~mask;
	else
		CANx->FM1R |= mask;

	if (fifo == CAN_FIFO0)
		CANx->FFA1R &= ~mask;
	else
		CANx->FFA1R |= mask;

	CANx->FA1R |= mask;
	CANx->FMR &= ~CAN_FMR_FINIT;
	return CAN_OK;
}

tjb12345
Posts: 11
Joined: Sun Aug 06, 2017 6:23 am

Re: CAN Bus Library for STM32F103

Post by tjb12345 » Wed Sep 13, 2017 4:40 am

I ran into the same issue. After studying the registers I figured out that the filter and mask need to be shifted left before they are put in the FR1 and FR2 registers. Standard IDs need to be shifted 21 bits (11 bits for STD ID, moved 21 to left to move it to the upper most bits of the register). and EXT ID must be shifted 3 bits, and then set the EXT ID Bit. Here is my modified function:

Code: Select all

CAN_STATUS can_filter(CAN_Port* CANx, uint8 filter_idx, CAN_FIFO fifo, CAN_FILTER_SCALE scale, CAN_FILTER_MODE mode, uint32 fr1, uint32 fr2, int extID)
{
	uint32 mask = ((uint32)0x00000001) << filter_idx;

	CANx->FMR |= CAN_FMR_FINIT;		// Initialization mode for the filter
	CANx->FA1R &= ~mask;			// Deactivation filter


	if (scale == CAN_FILTER_32BIT)
		CANx->FS1R |= mask;
	else
		CANx->FS1R &= ~mask;
	if (extID) {
		CANx->sFilterRegister[filter_idx].FR1 = (fr1 << 3) | CAN_ID_EXT;
		CANx->sFilterRegister[filter_idx].FR2 = (fr2 << 3) | CAN_ID_EXT;	
	}
	else {
		CANx->sFilterRegister[filter_idx].FR1 = (fr1 << 21);
		CANx->sFilterRegister[filter_idx].FR2 = (fr2 << 21);	
	}
	

	if (mode == CAN_FILTER_MASK)
		CANx->FM1R &= ~mask;
	else
		CANx->FM1R |= mask;

	if (fifo == CAN_FIFO0)
		CANx->FFA1R &= ~mask;
	else
		CANx->FFA1R |= mask;

	CANx->FA1R |= mask;
	CANx->FMR &= ~CAN_FMR_FINIT;
	return CAN_OK;
}
My project only uses EXT ID's but I opted to add a parameter to the filter function to indicate whether is ext ID filter or standard. That parameter needs to be added in 4 places, can.h, can.c, HardwareCAN.h and HardwareCan.cpp.

macbeth
Posts: 13
Joined: Fri Jun 17, 2016 12:59 pm

Re: CAN Bus Library for STM32F103

Post by macbeth » Wed Sep 13, 2017 3:56 pm

Just wanted to ask if the core file changes finally made it "upstream" ... Any news from the master of merging?
If not, would it be possible to maintain an up-to-date branch with phono's fantastic patches?

@phono: thanks for your help with the CAN short ciruit-recovery!

User avatar
RogerClark
Posts: 6917
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: CAN Bus Library for STM32F103

Post by RogerClark » Wed Sep 13, 2017 9:54 pm

macbeth wrote:
Wed Sep 13, 2017 3:56 pm
Just wanted to ask if the core file changes finally made it "upstream" ... Any news from the master of merging?
If not, would it be possible to maintain an up-to-date branch with phono's fantastic patches?

@phono: thanks for your help with the CAN short ciruit-recovery!

did anyone generate a PR??

I dont recall seeing one ....

Phono
Posts: 90
Joined: Tue May 05, 2015 6:08 am
Location: Ermont, France

Re: CAN Bus Library for STM32F103

Post by Phono » Thu Sep 14, 2017 12:45 pm

I am definitely not easy with Git, so I did not issue a PR.
Since some people here have successfully integrated the HardwareCAN library into their cores, could someone perform the PR on my behalf? I can check for correctness afterwards, if you wish.

pioneer
Posts: 15
Joined: Fri Apr 22, 2016 8:11 am

SN65HVD230 CAN Board

Post by pioneer » Sat Sep 16, 2017 10:08 am

Hi everyone.

Have anyone worked with SN65HVD230 CAN Board? http://www.waveshare.com/wiki/SN65HVD230_CAN_Board

I just found out about the CAN bus few days ago. I have no idea how to write any code for my STM32F103VET6 board. http://www.ebay.com/itm/STM32F103VET6-A ... Sw2XFUh7Ay

As I saw in my micro controller data sheet PA11 for CAN_RX and PA12 for CAN_TX. Is this where I connect to SN65HVD230 CAN Board RX and TX?

I have no idea how to write any code to sending or receiving between those SN65HVD230 CAN Board modules. Any sample code will be greatly appreciate. Thanks in advance.

User avatar
And_Ru
Posts: 25
Joined: Thu Nov 10, 2016 1:16 pm
Location: Russia, Moscow

Re: CAN Bus Library for STM32F103

Post by And_Ru » Fri Sep 22, 2017 8:39 am

Phono wrote:
Thu Sep 14, 2017 12:45 pm
I am definitely not easy with Git, so I did not issue a PR.
Since some people here have successfully integrated the HardwareCAN library into their cores, could someone perform the PR on my behalf? I can check for correctness afterwards, if you wish.
I can try to PR. Could you check this branch: https://github.com/megadrifter/Arduino_ ... GMLAN-test ?
I can also try to incorporate changes proposed by tjb12345

@to all:
I can activate USB instead of CAN, but why it is not possible to Serial upload? (initially I upload via ST-link)
The datasheet says
The USB
and CAN can be used in the same application but not at the same time.

Phono
Posts: 90
Joined: Tue May 05, 2015 6:08 am
Location: Ermont, France

Re: CAN Bus Library for STM32F103

Post by Phono » Fri Sep 22, 2017 1:39 pm

@And_Ru:
There are differences with my code, since I did not commit all my changes. Could you please alter your files as follows:

*******************************************************************************
1-File CAN.C

Lines 106 to 110 included, should read:

Code: Select all

// JMD 2017/07/18 -- added volatile to fix queue problems, removed can_rx_count
volatile uint8 can_rx_head;
volatile uint8 can_rx_tail;
volatile uint8 can_rx_lost;
uint8 can_active = 0;
Starting from line 165: please replace the function code with this one:

Code: Select all

CAN_STATUS can_deinit(CAN_Port* CANx)
{
	if (CANx == CAN1_BASE)
	{
		nvic_irq_disable(NVIC_USB_LP_CAN_RX0);	// Disable interrupts
		nvic_irq_disable(NVIC_CAN_RX1);
		nvic_irq_disable(NVIC_USB_HP_CAN_TX);
		__asm volatile( "dsb" );						// Synchronization of the pipeline to guarantee
		__asm volatile( "isb" );						// that the protection against interrupts is effective
		rcc_reset_dev(RCC_CAN);
		rcc_clk_disable(RCC_CAN);
		can_active = 0;
	}
	return (status = CAN_OK);
}
Line 193 : please replace corresponding lines:

Code: Select all

CAN_STATUS can_init(CAN_Port* CANx, uint32 control, uint8 speed)
{
	status = CAN_INIT_FAILED;			// default result status
										// initialize receive message queue
	can_rx_head = can_rx_tail = can_rx_lost = 0;

	rcc_reset_dev(RCC_USB);			//! X893
	rcc_clk_disable(RCC_USB);		//! X893

	rcc_clk_enable(RCC_AFIO);			// enable clocks for AFIO
	rcc_clk_enable(RCC_CAN);			// and CAN
	rcc_reset_dev(RCC_CAN);				// reset CAN interface

	can_active = 1;						// set CAN active flag (for interrupt handler

	CANx->MCR &= ~CAN_MCR_SLEEP;		// reset CAN sleep mode (default after reset)

	if (can_init_enter(CANx) != CAN_OK)	// enter CAN initialization mode
		return status;					// error, so return

	CANx->MCR &= ~CAN_CONTROL_MASK;		// set mode bits
	CANx->MCR |= (control & CAN_CONTROL_MASK);

	CANx->BTR &= ~CAN_TIMING_MASK;			// Set the bit timing register
	CANx->BTR |= (can_speed_table[speed].btr & CAN_TIMING_MASK);

	nvic_irq_enable(NVIC_USB_LP_CAN_RX0);	// Enable interrupts
	nvic_irq_enable(NVIC_CAN_RX1);
    
	nvic_irq_enable(NVIC_USB_HP_CAN_TX);

	CANx->IER = (CAN_IER_FMPIE0 | CAN_IER_FMPIE1 | CAN_IER_TMEIE);

Please replace following two functions as follows:

Code: Select all

void can_rx_queue_clear(void)
{
	nvic_irq_disable(NVIC_USB_LP_CAN_RX0);
	nvic_irq_disable(NVIC_CAN_RX1);
	__asm volatile( "dsb" );						// Synchronization of the pipeline to guarantee
	__asm volatile( "isb" );						// that the protection against interrupts is effective
	can_rx_head = can_rx_tail = can_rx_lost = 0;					// JMD 2017/07/18
	nvic_irq_enable(NVIC_USB_LP_CAN_RX0);
	nvic_irq_enable(NVIC_CAN_RX1);
}

// JMD 2017/07/18 -- changed
uint8 can_rx_available(void)
{
	if ( can_rx_head >= can_rx_tail )
		return can_rx_head - can_rx_tail ;
	else
		return CAN_RX_QUEUE_SIZE - ( can_rx_tail - can_rx_head ) ;
}
Next add following function:

Code: Select all

// JMD 2017/07/18 -- added
uint8 can_frame_lost(void)
{
	if ( can_rx_lost != 0 )
	{
		can_rx_lost = 0 ;
		return 1 ;
	}
	return 0 ;
	
}
Then replace next two functions:

Code: Select all

CanMsg* can_rx_queue_get(void)
{
	if (can_rx_head == can_rx_tail)			// JMD 2017/07/18 -- changed
		return NULL;
	return &(can_rx_queue[can_rx_tail]);
}


void can_rx_queue_free(void)
{
	if (can_rx_head != can_rx_tail)			// JMD 2017/07/18 -- changed
	{
		nvic_irq_disable(NVIC_USB_LP_CAN_RX0);			// JMD atomicity problem
		nvic_irq_disable(NVIC_CAN_RX1);
		__asm volatile( "dsb" );						// Synchronization of the pipeline to guarantee
		__asm volatile( "isb" );						// that the protection against interrupts is effective
		can_rx_tail = (can_rx_tail == (CAN_RX_QUEUE_SIZE - 1)) ? 0 : (can_rx_tail + 1);

		nvic_irq_enable(NVIC_USB_LP_CAN_RX0);			// fin JMD problème d'atomicité
		nvic_irq_enable(NVIC_CAN_RX1);
	}
}
Next replace following function:

Code: Select all

void can_rx_read(CAN_Port* CANx, CAN_FIFO fifo)
{
	if (can_rx_available() < CAN_RX_QUEUE_SIZE)		// read the message - JMD 2017/07/18 -- changed
	{
		CanMsg* msg = &can_rx_queue[can_rx_head];
		can_read(CANx, fifo, msg);
		can_rx_head = (can_rx_head == (CAN_RX_QUEUE_SIZE - 1)) ? 0 : (can_rx_head + 1);

	}
	else
		can_rx_lost = 1;						// no place in queue, ignore package

	can_rx_release(CANx, fifo);
}
And last, add following function:

Code: Select all

// Addition JMD: the messages stored in fifo1 must also trigger an interrupt.
void __irq_can_rx1(void)
{
	CAN_RX0_IRQ_Handler() ;
}
*******************************************************************

2 - File HardwareCAN.cpp

add following method anywhere:

Code: Select all

uint8 HardwareCAN::frame_lost(void)
{
	return can_frame_lost() ;
}
and also add an entry to the class definition in HardwareCAN.h, in the public: section.

The reason of these changes is that there were lost frames due to the lack of the volatile qualifier. Then I have added a (probably useless) protection against interrupts, to guarantee that all variables will be fully processed when an interrupt occurs, despite the lag created by the instruction pipeline.

I also have removed the variable count, as its value could be derived from the two fifo indexes, so it created redundancy.

I have checked the changes in the filter mechanism. Actually I never used them, and though I did some fixes, there still were big mistakes! Thanks to tjb12345!

I have also checked the core files and found no error.

Please note that there is an error in the documentation, in file changes.h of the example. The lines 33 & 34 should read

Code: Select all

uint8 __attribute__((weak)) CAN_RX0_IRQ_Handler(void)
{ return 0 ; }      // Dummy ISR 
as I explained in an earlier post of this thread.

Please note that when the core is altered, this file is no more necessary and should be removed from the example project (as well as the include statement of file HardwareCANexample.ino).

Sorry for this cumbersome way of working, but I feel much safer this way. Thank you for undertaking this job.

Jean-Marc

User avatar
And_Ru
Posts: 25
Joined: Thu Nov 10, 2016 1:16 pm
Location: Russia, Moscow

Re: CAN Bus Library for STM32F103

Post by And_Ru » Tue Sep 26, 2017 8:59 pm

Phono wrote:
Fri Sep 22, 2017 1:39 pm
If possible, just send me these new files. E-mail see in private messages.

User avatar
RogerClark
Posts: 6917
Joined: Mon Apr 27, 2015 10:36 am
Location: Melbourne, Australia
Contact:

Re: SN65HVD230 CAN Board

Post by RogerClark » Tue Sep 26, 2017 10:54 pm

FYI. I just moved this post to the CAN Bus thread, as it had not been answered and it seemed to have been posted in the wrong place
pioneer wrote:
Sat Sep 16, 2017 10:08 am
Hi everyone.

Have anyone worked with SN65HVD230 CAN Board? http://www.waveshare.com/wiki/SN65HVD230_CAN_Board

I just found out about the CAN bus few days ago. I have no idea how to write any code for my STM32F103VET6 board. http://www.ebay.com/itm/STM32F103VET6-A ... Sw2XFUh7Ay

As I saw in my micro controller data sheet PA11 for CAN_RX and PA12 for CAN_TX. Is this where I connect to SN65HVD230 CAN Board RX and TX?

I have no idea how to write any code to sending or receiving between those SN65HVD230 CAN Board modules. Any sample code will be greatly appreciate. Thanks in advance.

Post Reply