CAN Bus Library for STM32F103

Can someone help me port this library?
Phono
Posts: 90
Joined: Tue May 05, 2015 6:08 am
Location: Ermont, France

Re: CAN Bus Library for STM32F103

Post by Phono » Mon Apr 10, 2017 7:49 pm

@And_Ru: the delay between frames seem strange to me. I never observed it. My applications run at 125 kb/s and I can send quite a few frames at only a few milliseconds interval.

mobi123
Posts: 4
Joined: Fri Feb 17, 2017 7:45 am

Re: CAN Bus Library for STM32F103

Post by mobi123 » Wed May 03, 2017 7:15 am

Phono wrote:@And_Ru: the delay between frames seem strange to me. I never observed it. My applications run at 125 kb/s and I can send quite a few frames at only a few milliseconds interval.
typedef enum CAN_GPIO_MAP {
CAN_GPIO_PB8_PB9, /* RX to PB8, TX to PB9 */
CAN_GPIO_PD0_PD1 /* RX to PD0, TX to PD1 */
} CAN_GPIO_MAP;

Can I add RX to PA11, TX to PA12?

mobi123
Posts: 4
Joined: Fri Feb 17, 2017 7:45 am

Re: CAN Bus Library for STM32F103

Post by mobi123 » Tue May 09, 2017 2:56 am

Code: Select all



CAN_STATUS can_gpio_map(CAN_Port* CANx, CAN_GPIO_MAP map_mode)
{
	rcc_clk_enable(RCC_AFIO);

	status = CAN_INIT_FAILED;
	if( CANx == CAN1_BASE)
	{
		switch(map_mode)
		{
		case CAN_GPIO_PB8_PB9:
			rcc_clk_enable(RCC_GPIOB);
			afio_remap(AFIO_MAPR_CAN_REMAP_PB8_PB9);
			gpio_set_mode(GPIOB, 8, GPIO_INPUT_FLOATING);
			gpio_set_mode(GPIOB, 9, GPIO_AF_OUTPUT_PP);
			break;
		case CAN_GPIO_PA11_PA12:
			rcc_clk_enable(RCC_GPIOA);
			afio_remap(AFIO_MAPR_CAN_REMAP_NONE);
			gpio_set_mode(GPIOA, 11, GPIO_INPUT_FLOATING);
			gpio_set_mode(GPIOA, 12, GPIO_AF_OUTPUT_PP);
			break;
#if NR_GPIO_PORTS >= 4
		case CAN_GPIO_PD0_PD1:
			rcc_clk_enable(RCC_GPIOD);
			afio_remap(AFIO_MAPR_CAN_REMAP_PD0_PD1);
			gpio_set_mode(GPIOD, 0, GPIO_INPUT_FLOATING);
			gpio_set_mode(GPIOD, 1, GPIO_AF_OUTPUT_PP);
			break;
#endif
		default:
			return status;
		}
		status = CAN_OK;
	}
	return status;
}
HardwareCAN/src/utility/can.c

Code: Select all


typedef enum CAN_GPIO_MAP {
	CAN_GPIO_PB8_PB9,		/* RX to PB8, TX to PB9 */
	CAN_GPIO_PD0_PD1,		/* RX to PD0, TX to PD1 */
	CAN_GPIO_PA11_PA12
} CAN_GPIO_MAP;
HardwareCAN/src/utility/can.h
Last edited by mobi123 on Tue May 09, 2017 3:02 am, edited 1 time in total.

mobi123
Posts: 4
Joined: Fri Feb 17, 2017 7:45 am

Re: CAN Bus Library for STM32F103

Post by mobi123 » Tue May 09, 2017 3:01 am

Now there is a gateway to receive data to send the mailbox to the TXRQ bit after the MCU is dead.
If there is no gateway to the case can always send data, how to solve this?

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 » Sun May 28, 2017 7:26 am

Phono wrote:@And_Ru: the delay between frames seem strange to me. I never observed it. My applications run at 125 kb/s and I can send quite a few frames at only a few milliseconds interval.
You're right, I had error in my code.

How do I use other pins for CAN? I want to connect two mcp2551 trancievers to two CAN buses and switch between them. How fast will bee switchover?

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 » Sun May 28, 2017 12:10 pm

...
Last edited by And_Ru on Fri Jun 02, 2017 6:56 am, edited 2 times in total.

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 » Thu Jun 01, 2017 7:56 pm

Hello.
I try to use two CAN buses and switch between them via remap. But it does not work. Could you analyze?
Code is below.
First it sends out the message with ID 0x100 to the bus on A11A12 pins, but then nothing there. On the B8B9 pins then I get working cycle with messages of ID 0x111. And all further messages with ID 0x100 go also here with speed 33.
What am I doing wrong?
Not possible to remap on-the-fly?

Code: Select all

#include <HardwareCAN.h>
//#include "changes.h"
/*
 *
 */

#define T_DELAY 10
// Instanciation of CAN interface
HardwareCAN canBus(CAN1_BASE);
CanMsg msg ;

void CAN_a_33_Setup(void)
{
  CAN_STATUS Stat ;
  canBus.map(CAN_GPIO_PA11_PA12);  
  Stat = canBus.begin(CAN_SPEED_33, CAN_MODE_NORMAL);
  canBus.filter(0, 0, 0);
  canBus.set_irq_mode();
  Stat = canBus.status();
  if (Stat != CAN_OK)
  {digitalWrite(PC13, LOW);
   delay(10000);}
// /* Your own error processing here */  ;  // Initialization failed
//  delay(T_DELAY);
 }

void CAN_b_95_Setup(void)
{
  canBus.map(CAN_GPIO_PB8_PB9);
  Stat = canBus.begin(CAN_SPEED_95, CAN_MODE_NORMAL);
  canBus.filter(0, 0, 0);
  canBus.set_irq_mode();
  Stat = canBus.status();
  if (Stat != CAN_OK)
  {digitalWrite(PC13, LOW);
   delay(10000);}
//     /* Your own error processing here */ ;   // Initialization failed
//  delay(T_DELAY);
}


CAN_TX_MBX CANsend(CanMsg *pmsg) 
{
  CAN_TX_MBX mbx;

  do 
  {
    mbx = canBus.send(pmsg) ;
#ifdef USE_MULTITASK
    vTaskDelay( 1 ) ;                 // Infinite loops are not multitasking-friendly
#endif
  }
  while(mbx == CAN_TX_NO_MBX) ;       // Waiting outbound frames will eventually be sent, unless there is a CAN bus failure.
  return mbx ;
}

// Send message
// Prepare and send a frame containing some value 
void SendCANmessage(long id=0x001, byte dlength=8, byte d0=0x00, byte d1=0x00, byte d2=0x00, byte d3=0x00, byte d4=0x00, byte d5=0x00, byte d6=0x00, byte d7=0x00)
{
  // Initialize the message structure
  // A CAN structure includes the following fields:
  msg.IDE = CAN_ID_STD;          // Indicates a standard identifier ; CAN_ID_EXT would mean this frame uses an extended identifier
  msg.RTR = CAN_RTR_DATA;        // Indicated this is a data frame, as opposed to a remote frame (would then be CAN_RTR_REMOTE)
  msg.ID = id ;                  // Identifier of the frame : 0-2047 (0-0x3ff) for standard idenfiers; 0-0x1fffffff for extended identifiers
  msg.DLC = dlength;                   // Number of data bytes to follow

  // Prepare frame : send something
  msg.Data[0] = d0 ;
  msg.Data[1] = d1 ;
  msg.Data[2] = d2 ;
  msg.Data[3] = d3 ;
  msg.Data[4] = d4 ;
  msg.Data[5] = d5 ;
  msg.Data[6] = d6 ;
  msg.Data[7] = d7 ;

  digitalWrite(PC13, LOW);    // turn the onboard LED on
  CANsend(&msg) ;      // Send this frame            
  digitalWrite(PC13, HIGH);   // turn the LED off 
  delay(T_DELAY);  
}


// The application program starts here
byte msgD0 = 0x00;
void setup() {        // Initialize the CAN module and prepare the message structures.
  pinMode(PC13, OUTPUT);
  digitalWrite(PC13, HIGH);
  delay(10);
  digitalWrite(PC13, LOW);
  delay(1000);
  digitalWrite(PC13, HIGH);
  delay(1000);

}

void loop() {
  CAN_a_33_Setup();
  delay(T_DELAY);
  SendCANmessage(0x100,1,msgD0);       
  delay(T_DELAY);
  CAN_b_95_Setup();
  delay(T_DELAY);
  SendCANmessage(0x111,1,msgD0);       
  delay(T_DELAY);
  msgD0++;
}

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 » Wed Jun 07, 2017 9:49 pm

So, the answer is
afio_init();
Before switching back to A pins.

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

Re: CAN Bus Library for STM32F103

Post by macbeth » Wed Jun 14, 2017 11:38 am

I'm just looking at some CAN issues at the moment. I had CAN working on a "maple"-clone with the libmaple toolchain. Now I'd like to switch to STM32duino (or rather platformIO).

Could you tell me what the status of the HardwareCAN integration is? I saw phono's great branch with HardwareCAN (thanks, man!!). Would it be a big problem to pull these changes into master? Are the modifications (rcc.c, rcc.h, ...) breaking anything else?

Looking at https://github.com/rogerclarkmelbourne/ ... og-patch-1 it seems that there's not too much to do. But then... I'm not in the position to judge the side effects. I usually don't look much under the hood.

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

Re: CAN Bus Library for STM32F103

Post by Phono » Wed Jul 19, 2017 4:12 pm

Please users of this library: note that as of today, I have committed a new version that fixes a bug that caused received frames to be occasionnally dropped or corrupted.
In my case, in my system with about 100 frames per second, lost frames occurred several times a day, and one or two corrupted frames a day.
Please update your programming environment for a more robust operation of CAN.

Post Reply