Can someone create a CAN library similar to the MCP2515 library for Arduino? That library is intuitive and easy to use, even for users who know almost nothing about CAN.
The MCP2515 Library can be found here: https://github.com/coryjfowler/MCP_CAN_lib
the maple world already has a CAN library that eventually worked with some effort and various contributions, including mine.
you can have a look here : http://forums.leaflabs.com/topic.php?id=802
I think I will try to port it to Arduino when I have the time to do it. So far, the Maple version works pretty well.
http://akb77.com/g/files/media/Maple.Ha … 0.0.12.rar
as its been over a year since anyone was active on the maple forum, discussing this, and there may also be updates in the forum not incorporated into this code.
It may not even compile
i.e Its unlikely that you can just replace the rcc.c and usb.c files with the ones from that download, as almost certainly rcc.c has been updated since those files were crated (in 2012) and I suspect so has usb.c
You’d need to diff those files against the ones shipped as part of the maple IDE back in 2012 (the IDE can still be download), and determine what changes were made by the author, then you’d need to apply the same changes to the current copies of usb.c and rcc.c and .h
Without actually doing all that myself, I have no idea how easy or complex, it would be to merge in the changes.
Please feel free to work out what needs to be updated and preferably send me a pull request when you’ve updated the core.
But I don’t have time to add CAN support at the moment, and I’m not even sure I have any CAN devices to test with, even if I did have time to look at this.
Thanks
Roger
I am sorry I had no time yet to work on this port. If you browse the thread in the Maple forum (http://forums.leaflabs.com/topic.php?id=802), you will find mentions of changes in USB and RCC.
This is because in the stm32f103cbt6 used in Maple and Olimexino boards, the USB and the CAN are mutually exclusive, since they use a shared portion or the memory (which is a pity, for you cannot debug a CAN application by writing information to the SerialUSB channel).
In addition, the CAN and the USB share a common interrupt vector.
In the original library, they had forgotten to add the switch to route the interrupt either to the USB or to the CAN processing. Which I added.
The drawback is that I had to declare an identifier in the core, which belongs to the CAN library. So far, I have to include the CAN library in every project, even if it does not use the CAN, just because the lacking identifier would produce a compile error.
In my contribution in the forum, you will see the lines that are changed in both USB.c and RCC.c and .h.
Roger Clark is right saying these files are likely to have changed since the version I used; but if you only do the mentioned changes in the current core files, I guess it will work.
If by the way you find a means to relieve the user from the need to include the CAN library when it is not needed, It would be great.
Regards,
Jean-Marc
Did you try using a weak reference to a dummy identifer?
The core code does this quite a lot for default ISRs
To peppeve : I know the sharing is annoying, but with olimexino boards it is very convenient to use the built-in CAN without any shield or extension. If you need a serial port you still can use a physical port plus a FTDI adapter. Which I did recently because I needed a data rate of 115,200 bps on the serial port, and the fake serial port via USB is very slow.
The Due core code makes some use of weak references which is easy to understand
see
https://github.com/arduino/Arduino/blob … Serial.cpp
starting at line 38
then on line 66
Perhaps the same technique can be used for CAN.
i.e add weak refs to the core, and checks in the core, that only call the CAN function if it really exists ?.
Yes, the Olimexino STM32 board has the CAN transceiver built-in and a screw header for directly connecting the CAN bus. Very nice !
Any updates on CAN Library?
However, if someone could handle the integration of the library into the new environment, I am available to help with the CAN side of the things.
So if someone is willing to try and port the Maple-compatible CAN library to Arduino, let him call on me, and I will give him support for this task.
Sorry for not being able to do more so far.
I am not familiar with the push request stuff, which held me from submitting it so far.
If someone would like to help me, I could send him the files.
– create your own account on github
– log into it
– navigate to Roger’s github
– click on Fork button on upper right corner (this will create a fork into your account)
– use “git clone <you forked github URL>” in a location of your choice on your local disk.
– add the new library into the tree, then do “git add <the library folder>”
– git commit -m “the comment describing the new lib”
– git push (it will push the change into github web)
– navigate back on you github web and press “compare” button, it will show diffs against Roger’s main branch.
– click on “Create a Pull Request” and provide comments to Roger.
I am not sure if I could personally test this, as I am not sure I have any CANBus hardware.
I may have a digital compass somewhere which is CANBus but it was scavenged from an old quadcopter and I have no idea what type it is.
You would need to test with hardware from other vendors.
My question is: where in the directory tree must I put this explanation file? At the root of the HardwareCAN library, perhaps?
However, I do not yet master Git, so I may have done it the wrong way. Could you please check that the library is complete, and that 3 files are submitted to replace 3 files in 3 different directories of the core?
Thanks.
PR’s are in a state of flux at the moment, so I think I need to clear the backlog before I process yours.
There are some others relating to USB Serial, which may impact on yours as well, due to the shared interrupt, but I won’t know for sure until I merge the existing PRs
git add– STM32F1/libraries/HardwareCAN for the library;
– STM32F1\cores\maple\libmaple\rcc_f1.c
– STM32F1\system\libmaple\stm32f1\include\series\rcc.h
– STM32F1\cores\maple\libmaple\usb\stm32f1\usb.c
Can you check?
If there is something wrong, please help me fixing it.
I can’t find the CAN Bus library in your github repo.
https://github.com/Phonog/Arduino_STM32/
– usb.c in STM32F1/cores/maple/libmaple/usb/stm32f1/
– rcc.h in STM32F1/system/libmaple/stm32f1/include/series/
– rccf1.c in /STM32F1/cores/maple/libmaple/
and the library in STM32F1/libraries/
However, when I look at the comparison result (the link you mention), I find rcc.h, rccf1.c and usb.c in the library directory.
So I do not understand. However, all the files are there. If you can fix the location error, it is ok.
I apologize for a few comments in french I overlooked to translate in english.
I want to test it connecting to MCP2515 board (wich I also need to explore).
Actually, in hindsight, you are better off staying with LibMaple as the core for at least the next 6 months as to use CAN on the new core would require a lot of rewriting as the STM core uses STM’s own HAL (not libmaple) so there would need to be a lot of changes to port to that core.
If you need only one wire, you may want to look at the NCV7356 for example.
If you need only one wire, you may want to look at the NCV7356 for example.
I don’t know what’s the big deal here??? The MCP2515 shield for Arduino works perfectly with Iteadmaple 1.0 Arduino compatible board. The library compiles the board inits and then all runs smooth and easy like Arduino accept it’s much faster. All you need to do is a little bit rewire it. Not all of the CAN_BUS shield pins goes to the board. But if you really wants then you defanatelly figure it out. Program board through the Arduino IDE…
Also it works with Teensy 3.1 3.2.. Without any problem..
Though seems no body here actually tryd to hook up the PCM2515 CAN shield with STM. I did.. that’s why Im here to tall you about.
My first mistake was to connect CAN bus directly to the board (CAN TX, RX).
Second fail was because TJA1050 that I tried was defective (infinite resistance between CAN Hi – CAN Lo).
Third – both TJA1050 and MCP2515 must be supplied with 5V to be able to send messages.
I’ve simplified the code by Phono to just send a message for test reasons:
// HardwareCAN_simplified_send1.ino
#include <HardwareCAN.h>
//#include "changes.h"
/*
* Example of use of the HardwareCAN library
* Please read the file changes.h to see the changes to be performed to the core in order to use this
*/
byte msgD0 ; // variable to be used in the example.
// Instanciation of CAN interface
HardwareCAN canBus(CAN1_BASE);
CanMsg msg ;
void CANSetup(void)
{
CAN_STATUS Stat ;
// Initialize CAN module
canBus.map(CAN_GPIO_PB8_PB9); // This setting is already wired in the Olimexino-STM32 board
Stat = canBus.begin(CAN_SPEED_125, CAN_MODE_NORMAL); // Other speeds go from 125 kbps to 1000 kbps. CAN allows even more choices.
canBus.filter(0, 0, 0);
canBus.set_irq_mode(); // Use irq mode (recommended), so the handling of incoming messages
// will be performed at ease in a task or in the loop. The software fifo is 16 cells long,
// allowing at least 15 ms before processing the fifo is needed at 125 kbps
Stat = canBus.status();
if (Stat != CAN_OK)
/* Your own error processing here */ ; // Initialization failed
}
// Send one frame. Parameter is a pointer to a frame structure (above), that has previously been updated with data.
// If no mailbox is available, wait until one becomes empty. There are 3 mailboxes.
CAN_TX_MBX CANsend(CanMsg *pmsg) // Should be moved to the library?!
{
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 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 = 8; // 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
delay(180);
digitalWrite(PC13, HIGH); // turn the LED off
delay(100);
}
// The application program starts here
void setup() {
// put your setup code here, to run once:
CANSetup() ; // Initialize the CAN module and prepare the message structures.
pinMode(PC13, OUTPUT);
msgD0 = 0x01;
}
void loop() {
delay(1000);
long msgID = 0x101 ;
SendCANmessage(msgID, msgD0) ;
msgD0++;
}
to add new speeds, you have to change the code at two places as shown below.
I am unsure of the numeric values to achieve these speeds. At least, it should work with a good physical bus line, but fine tuning the values SJW, TS1 and TS2 may further improve the robustness of the communication.
i have never heard of these speeds. To satisfy my curisosity, where are they used?
1) in the file can.h, change the enum definition:
enum CAN_SPEED {
CAN_SPEED_125,
CAN_SPEED_250,
CAN_SPEED_500,
CAN_SPEED_1000,
};
Another place found in HardwareCAN.cpp (otherwise Arduino compiler don’t pass it):
/**
* @brief Initialize a CAN peripheral
* @param freq frequency to run at, must one of the following values:
* - CAN_SPEED_1000
* - CAN_SPEED_500
* - CAN_SPEED_250
* - CAN_SPEED_125
* - CAN_SPEED_95
* - CAN_SPEED_33
*/!stephen
I also have ready a thread-safe version of the Ethernet library. Anyone interested?
So I’ve pulled your changes to a separate branch
https://github.com/rogerclarkmelbourne/ … og-patch-1
So if anyone wants to use them, they can use that branch
Phono: I’d be interested to try your library – if you can create a new branch for that or ?
the schematics of the blue pill indicates CAN_RX and CAN_TX for PB8 and PB9, so I do not see why it would not work.
Yes, I will issue a PR for the ethernet library.
Here is the video [youtube]https://www.youtube.com/watch?v=GJgBOnZgmis[/youtube]
Here is thecode:
It sends OK button on my button press and turns on the LED when see “SETTINGS” button is pressed.
I had to add more CAN speed settings into the library, so I’ve cloned it.
Also there’s simple example how to send.
I hope I can join in here. I just purchased an STM32F103 Nucelo dev board that I’m going to learn how to use. I come from a few years of Arduino background, tied with CANBUS and I’m hoping to switch over to STM32 since (a few of them) have CAN built in.
When I get my dev board I’ll start playing around with it and probably get the CAN library installed and see if I can get it to talk with my 2000 Saab 9-3 bus. I currently have an ATMEGA328P-AU talking via a MCP2515 and a SN65HVD231, so I think I can get things to work with only the 231 chip.
if I figure anything out I can post for others ![]()
Seth
message sent was good only for firs time then message sending freezes. Have experienced same thing?
https://github.com/rogerclarkmelbourne/ … og-patch-1
So if anyone wants to use them, they can use that branch
message sent was good only for firs time then message sending freezes. Have experienced same thing?
For refernce, I’ve used your simplified sending sketch and MCP2515 can module is attched to Arduino UNO on the receiving side.
Thank you again for your kind reply.
I send two messages in series and they appear in cansniffer with 0.28 seconds delay. Is it normal for CAN speed 95 kbps?
I have a load of Olimexino-STM32 boards (with onboard MCP2551 CAN transceiver) I’m planning to use for a home CAN network. I’ll happily help out with testing as required?
cheers,
Keith
I’ve been doing Lots of CANbus using the MCP2515 but always had to stick to standard Arduino Nano to avoid the dreaded 3.3V – 5V Issue.
Yes, transceivers do a great job but the higher the component count the lower is the reliability.
I’ve been using the Atmel SAMD21 (3.3V) but could not interface the MCP2515 directly. Now I can have more Mips/ More Memory
Can Tranceivers : Check into this: http://www.ebay.com/itm/SN65HVD230-CAN- … SwepJXbQj6
I’ve been using those on an arduino Due project.
Is there anything you’d like to be tested in perticular ?
My Ultimate dream : CANbus bootloader !
I was just about to lookinto it for the Arduino Nano or the SAMD21.
I did work an SDCard(SPI) bootloader for the SAMD21 and was about to look into a CANbus version …
But this 2$ PCB just tells me I should try on the STM… I’d be willing but I would like to know if someone else has interest to help out.
I could even work into the STM32Loader.py to support out work.
Imagine this, you seal your mini project in a proper casing to avoid environmental issues and you fidure out later you would like to add a new feature.
OKOK , I know you guys all do it best the first time around ! ![]()
Basically I would like it to work so that when I go to car and turn ignition on then stm32 starts up. When I leave the car then stm32 would go to sleep and not drain my battery.
Basically I would like it to work so that when I go to car and turn ignition on then stm32 starts up. When I leave the car then stm32 would go to sleep and not drain my battery.
Basically I would like it to work so that when I go to car and turn ignition on then stm32 starts up. When I leave the car then stm32 would go to sleep and not drain my battery.
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;
}
If there is no gateway to the case can always send data, how to solve this?
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?
#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++;
}
afio_init();
Before switching back to A pins.
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.
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.
However, I would like to request you to include in the next version of the core the few changes that are required to be able to include the library in a project. These changes are simple and cannot add a threat to the stability of the core.
Thanks in advance.
But I still have 2 more general questions (and this seems to be the thread where the CAN-geeks hang out)
1: Is there a way to reset the communication in case of a temporary short circuit of the CAN bus? Even when I try to escape the blocking while loop in CANsend I never again get mbx == CAN_TX_NO_MBX
CAN_TX_MBX CANsend(CanMsg *pmsg) {
uint32 ct=0;
CAN_TX_MBX mbx;
digitalWrite(BOARD_LED,1);
do
mbx = canBus.send(pmsg);
while (mbx == CAN_TX_NO_MBX && ct++<20000);
digitalWrite(BOARD_LED,0);
return mbx;
}
MCP2551 Blue Pill
TXD…………PB9
VSS…………GND
VDD………..5V
RXD……….PB8
Vref………Nothing
CAN H……to CAN H on CANBUS
CAN L……to CAN L on CANBUS
Rs……….to GND (through a 4.7k resistor….tried directly to GND, but the 4.7k is what use on the DUE and that works)
I have a FTDI setup on Serial1 to monitor the status, using PA2
The MPC2551 is a 5V transceiver, so on the DUE I use a logic level converter, and that works great. I tried with and without on the Blue Pill since PB8 and PB9 are 5V tolerant. I’m running at 250kbps on the baud, and I have that configured in the setup. I can’t tell what I have going on different that what And_Ru has in his video, but there must be something. Any ideas? I can post code if needed.
[Phono – Thu Jul 20, 2017 12:02 pm] –
@RogerClark: I understand that you are not experienced enough to support the HardwareCAN library, and thus, you did not include it in your last version.
However, I would like to request you to include in the next version of the core the few changes that are required to be able to include the library in a project. These changes are simple and cannot add a threat to the stability of the core.
Thanks in advance.
Is someone going to create a PR for this change?
been working on this yet, and I got it to send 1 message, and then it freezes. I received the first message on my Due. I tried different serial ports and no serial ports, but it still only sends 1 before freezing. I also added the digitalWrite in the main loop that fires every second to make sure it wasn’t just failing to send. It does not continue to blink. It is also not geting stuck in the No MBX loop anymore, as I put the digitalWrite there (with a small delay to make sure I could see the blink.)
Anyone out there?
EDIT: re-reading above posts and saw that jongjejung had the same issue, however its not clear what was wrong in his case. I definitely have 5V at the MPC2551.
#include <HardwareCAN.h>
/*
* Uses STM32duino with Phono patch. Must add 33 and 95 CAN speeds
*/
#define BPIN 0
#define SPIN 1
byte msgD0 ; // variable to be used in the example.
uint32_t lastSent = 0;
int count = 1;
int ledState = 0;
// Instanciation of CAN interface
HardwareCAN canBus(CAN1_BASE);
CanMsg msg ;
void CANSetup(void)
{
CAN_STATUS Stat ;
// Initialize CAN module
//Serial1.println("test1");
canBus.map(CAN_GPIO_PB8_PB9);
// Serial1.println("test2");// This setting is already wired in the Olimexino-STM32 board
Stat = canBus.begin(CAN_SPEED_250, CAN_MODE_NORMAL); // Other speeds go from 125 kbps to 1000 kbps. CAN allows even more choices.
// Serial1.print("Status: ");
// Serial1.println(Stat);
//Serial1.println("test3");
canBus.filter(0, 0, 0);
canBus.set_irq_mode(); // Use irq mode (recommended), so the handling of incoming messages
// will be performed at ease in a task or in the loop. The software fifo is 16 cells long,
// allowing at least 15 ms before processing the fifo is needed at 125 kbps
Stat = canBus.status();
if (Stat != CAN_OK){
// Serial1.println("CAN initialization Failed");
/* Your own error processing here */ ; // Initialization failed
}
}
// Send one frame. Parameter is a pointer to a frame structure (above), that has previously been updated with data.
// If no mailbox is available, wait until one becomes empty. There are 3 mailboxes.
CAN_TX_MBX CANsend(CanMsg *pmsg) // Should be moved to the library?!
{
CAN_TX_MBX mbx;
do
{
mbx = canBus.send(pmsg) ;
// Serial1.print("MBX: ");
// Serial1.println(mbx);
#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_EXT; // 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 ;
Serial2.println("before CANSend");
CANsend(&msg) ; // Send this frame
// Serial1.println("after CANSend");
}
// The application program starts here
int bState = 0; // variable for reading the pushbutton status
int sState = 0; // variable for reading the switch status
byte st = 0x31; // buttot 1 on the CD30MP3
void setup() {
// put your setup code here, to run once:
Serial2.begin(115200);
// Serial1.println("before CANSetup");
CANSetup(); // Initialize the CAN module and prepare the message structures.
pinMode(PC13, OUTPUT);
// pinMode(BPIN, INPUT); // input for hardware button
// pinMode(SPIN, INPUT); // input for hardware switch
// Serial1.println("Hello World!");
msgD0 = 0x01;
delay(500);
}
void loop() {
// bState = digitalRead(BPIN);
// sState = digitalRead(SPIN);
//Serial1.println("loop");
// check if the pushbutton is pressed.
// if it is, the buttonState is HIGH:
uint32_t currentMillis = millis();
if ((currentMillis - lastSent) >= 1000) {
digitalWrite(PC13, ledState);
ledState != ledState;
lastSent = currentMillis;
uint32_t msgID = 0x1CFFEEF0 ;
// Serial1.print("start CAN Message: ");
// Serial1.println(count);
SendCANmessage(msgID, 3, 0x01, 0x6f, count) ;
count++;
}
// check if the switch is high.
// if it is:
// try to read message and output to serial
CanMsg *r_msg;
if ((r_msg = canBus.recv()) != NULL){
// Serial1.print(r_msg->ID);
// Serial1.print("#");
// Serial1.print(r_msg->Data[0]);
// Serial1.print(".");
// Serial1.print(r_msg->Data[1]);
// Serial1.print(".");
// Serial1.print(r_msg->Data[2]);
// Serial1.print(".");
// Serial1.print(r_msg->Data[3]);
// Serial1.print(".");
// Serial1.print(r_msg->Data[4]);
// Serial1.print(".");
// Serial1.print(r_msg->Data[5]);
// Serial1.print(".");
// Serial1.print(r_msg->Data[6]);
// Serial1.print(".");
// Serial1.println(r_msg->Data[7]);
canBus.free();
}
}
@macbeth
Question 1 :
you can insert in the loop that processes incoming messages the following code:
if ( canBus.Port->ESR & CAN_ESR_BOFF )
CANSetup() ;
I double check tomorrow and report back.
Thanks much.
[Phono – Wed Aug 09, 2017 8:31 pm] –
@tjb12345:
looks like the transmit interrupt is not activated. Did you perform the changes in the two core files as described in the file changes.h of the example of the HardwareCAN library?@all: these changes in the core files are what I request RogerClark to include in the root to allow for integration of the library!
So I cleaned out the STM32 core files and started over, downloading the branch from RogerClark’s repo that he pulled in from your fork
this link: https://github.com/rogerclarkmelbourne/ … og-patch-1
Went through the changes.h file, but they were all made already, with one exception. (Im assuming since I am pulling from your fork?)
the only difference (unless im blind) is the last CAN_RX0_IRQ_Handler function. in the changes.h file it returns 1, but the core file had return 0. I changed it but it still gets hung.
I just got an Olimexino board delivered today, so im going to try with that as well to eliminate hardware, but I can take this same MPC2551 and hook it to my Due, and it works on that.
2.3.1) inserted 12 lines, position 186
// JMD : default ISRs of CAN, to be overridden if HardwareCAN library is used in sketch
void __attribute__((weak)) USB_HP_CAN_TX_IRQHandler(void)
{ ; } // Dummy ISR
void __irq_usb_hp_can_tx(void)
{
USB_HP_CAN_TX_IRQHandler () ;
}
uint8 __attribute__((weak)) CAN_RX0_IRQ_Handler(void)
{ return 1 ; } // Dummy ISR
The Blue pill sends the message and then freezes. I have replaced the 1.5k R10 resistor on the D+ line, and tried to see if there was other soldering issues, but I can’t find any. Tried it on a different board as well with same results. I know they are cheap clones, so maybe all the ones i have have something wrong with them.
For now I am going to continue my prototyping with the Olimexino-STM32 board, but I would like to use the blue pill if possible, as they are cheaper and smaller, and I already have a CAN transceiver board designed that matches up to it.
There is an error in my file changes.h.
the dummy interrupt service routine in C:\ArduinoForSTM32\arduino-1.6.9\hardware\Arduino_STM32-master\STM32F1\cores\maple\libmaple\usb\stm32f1\usb.c
should read
uint8 __attribute__((weak)) CAN_RX0_IRQ_Handler(void)
{ return 0 ; } // Dummy ISR
If you change it to 1, you crash the usb operation when the HardwareCAN library is not used.
I have only used the olimexino STM32 board, and it works. I did not try with another board. When you can, check with the olimexino board and tell me the result.
Thanks for the fix!
To recap:
It successfully sends 1 message, but then freezes (or gets stuck in a loop somewhere). I am using a MPC2551 Transceiver, which is verified to have 5 volts supplied to it. The code doesn’t work in Loopback Mode either though, so I am pretty sure it’s either the BP hardware, or the something in the STMF103C Generic Code (it works with the Maple (rev 3) code for the Olimexino board).
BP has been modified with 1.5k resistor in place of the 10k at R10. I hit the USB pins with the soldering iron to make sure there wasn’t a bad solder (not using USB though, uploading via serial to USART1 (PA9 and PA10). I was able to get the USB to work on the BP as well, running the BlinkNCount example, so that leads me to believe that the hardware is OK.
One difference is I used the USB to upload the CAN sketch to the Olimexino, but then used D7 , D8 for the Serial adapter to print the messages. on the Blue Pill, I am uploading right from the serial adapter, would that make any difference?
I am convinced that this will work, as it seems that someone else had it working earlier in the thread.
You can’t simply run CAN and expect USB to still run, unless you modify the USB system to co-exist
[RogerClark – Tue Aug 15, 2017 3:52 am] –
CAN and USB share hardware resources in the MCU.You can’t simply run CAN and expect USB to still run, unless you modify the USB system to co-exist
I’m not trying to use both…that why I’m uploading and running Serial through USART1 and an FTDI adapter. I only used the USB on the BlinkNCount Example to make sure that part actually worked.
Similar with the Olimexino, I used USB to upload the CAN sketch, but did not try to use SerialUSB to communicate with the serial monitor.
I’m just trying to figure out why when loaded onto a generic STM32F103C8 that it behaves differently than a STM32103RB. I do agree that the USB is probably whats
Did you select the serial uploaded option, then export the binary and then manually run DFU from the command line?
If you select bootloader upload from the menu in the IDE it enables all the USB subsystem code so that the sketch can be automatically triggered via USB to upload again the next time.
[RogerClark – Tue Aug 15, 2017 9:56 pm] –
Yes. If you choose Serial upload, the compile options remove all USB code, however most other options include the USB code
I knew there was going to be some little thing I was doing wrong……I got it working now! In loopback mode anyway, but I’m confident it will work other ways as well.
I am still not having luck uploading with USB after I flashed the PC13 Generic Bootloader, but I am able to program it using my ST-Link Tool and that option in the upload method, and It doesn’t make on difference to me anyway, since I can’t use USB for serial anyway.
I also tried adding a line to the boards.txt file like this
genericSTM32F103C.menu.upload_method.serialMethod.build.upload_flags=-DSERIAL_USB
But, I think there are more than one Define you may need to change
2) to remain USB serial in the board I just added the check of one pin in the setup:
Serial1.begin(115200);
pinMode(28, INPUT); // B12 = 16+12 = 28
digitalWrite(28, LOW);
delay(50);
Serial1.println("pin B12 set to input mode");
usbMode = digitalRead(28);
Serial1.print("pin B12 is ");
Serial1.println(usbMode);
if (usbMode)
{
Serial1.println("Entering USB mode");
Serial.begin(9600);
Serial.println("Entering USB mode");
while (1)
{
Serial.print(".");
Serial1.print(".");
digitalWrite(PC13, (!digitalRead(PC13)));
delay(1000);
}
}
else
{
digitalWrite(PC13, PC13OFF);
Serial1.println("Starting CAN module ...");
CANSetup() ; // Initialize the CAN module and prepare the message structures.
}
Serial1.println("Setup finished, going to loop()");
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;
}
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;
}
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!
[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!
did anyone generate a PR??
I dont recall seeing one ….
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.
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.
[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.
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.
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:
// 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;
[Phono – Fri Sep 22, 2017 1:39 pm] –
If possible, just send me these new files. E-mail see in private messages.
[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.
I did not use this board, but there is no reason why it should not work.
You just have to connect it to PA11 and PA12, and adapt the example in the HardwareCAN library to select these pins.
(Actually this library is under construction, and it will be available soon, I hope).
So far this library requires changes in the core, so either you do them manually, or you wait until the new version of the STM32 environment is available.
In the mean time, you can read the files you will find here :
https://github.com/megadrifter/Arduino_ … ardwareCAN
[RogerClark – Wed Sep 13, 2017 9:54 pm] –
did anyone generate a PR??
I’ve just made PR with core files change. Please check if this is what all we need.
https://github.com/rogerclarkmelbourne/ … 2/pull/355
also I added CAN speeds 33 and 95; CAN_GPIO_PA11_PA12 mapping.
This would need to be extensively tested by people using these timers
I could potentially push a branch with these changes, but it will take a while to get this complexity and risk of this change into the master, because everyone is “time poor” and its unlikely to get fully tested in the short term.
[RogerClark – Sat Oct 14, 2017 8:25 pm] –
I see the PR includes changes to things like the Hardware timers etcThis would need to be extensively tested by people using these timers
I could potentially push a branch with these changes, but it will take a while to get this complexity and risk of this change into the master, because everyone is “time poor” and its unlikely to get fully tested in the short term.
Hello Roger,
Actually only three files of the core are changed:
1) STM32F1\cores\maple\libmaple\rcc_f1.c
2) STM32F1\cores\maple\libmaple\usb\stm32f1\usb.c
3) STM32F1\system\libmaple\stm32f1\include\series\rcc.h
Others may be just out of date because of old fork.
I should add also:
[tjb12345 – Wed Sep 13, 2017 4:40 am] –
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.
Should I do another PR and cancell current, or just update my branch?
Sorry, github is still new for me.
I have a big merge pendinb to add USB HID etc, which may impact on your PR, also I would need to give your changes more visibility, as only a few people resd this thread.
I will need to start 2 new threads in general discussion about the proposed changes to USB and also for CAN.
As we now have thousands of users for thIs Core, I have to be careful when changing things at its heart.
So.. Until I find it, I would not be able to test the CAN code ![]()
I am not happy to see this, I rate the risk to something go wrong on serial USB quite high.
It does look risky
[And_Ru – Tue Oct 17, 2017 3:10 pm] –
Others may be just out of date because of old fork.
…
Sorry, github is still new for me.
I think your PR has pulled in several other changes that are unnecessary or incorrect. I would start again with a clean branch of the current Arduino_STM32 repo, and apply only the changes needed for CAN.
It seems some changes in USB are inevitable, because in the F1 the USB shares an ISR and other things with CAN. According to the comments in the PR, USB cannot run at the same time as CAN, but I’m not sure that is true in general. I think it is possible to run both USB and CAN but it may take some careful coding.
Edit; I quickly skimmed the thread and the shared buffer was mentioned at the start. The quote from the reference manual is (RM0008, pg.655)
Note: In low, medium-, high- and XL-density devices the USB and CAN share a dedicated 512-
byte SRAM memory for data transmission and reception, and so they cannot be used
concurrently (the shared SRAM is accessed through CAN and USB exclusively). The USB
and CAN can be used in the same application but not at the same time.
I think ST are being disingenuous here. The nature of comms is that you create a connection, then unsolicited data can arrive any time. ST seem to be suggested that you do some USB for a bit, then close it, do some CAN, close it, re-enumerate the USB and do some USB. I suppose in theory if you control the protocol on USB and CAN you could arrange for a strict ping-pong controlled by the F103, but that is a very special case and not practical.
I think practically speaking, USB and CAN can not be used in the same application on F103. Certainly in our Arduino case, we try to present an easy to use API for the user. I can’t think of a sensible way to prevent users trying to use USB and CAN concurrently. Any run time co-existence is going to tie USB and CAN fundamentally together, and generating a run time error is quite confusing for unsuspecting users.
So I’m not sure how to proceed with this. USB is pretty baked in to the Arduino_STM32 core. Enabling CAN means disabling USB, so operation of USB code becomes moot after that. I think the best we could do is minimise changes to USB, and as long as the user does not enable CAN those changes have no impact. The least change is to call a CAN interrupt hook in the USB interrupt, CAN without interrupts is pretty useless.
That seems a sensible approach.
BTW.
The change to merge USB HID into the master seems just as contentious, so I would advise that the dust left to settle on that, before CAN could be merged.
However, as USB HID PR seems to currently be in the process of updating and bug fixing by its author, I think CAN may have to wait quite a while
My preference is to integrate HID before CAN as the number of people who want HID is higher than the number of people who want CAN, and the number of people with CAN hardware is a small percentage of members, where as most people use USB ( even if only for Serial CDCACM)
[bobc – Wed Oct 18, 2017 10:07 am] –
I think your PR has pulled in several other changes that are unnecessary or incorrect. I would start again with a clean branch of the current Arduino_STM32 repo, and apply only the changes needed for CAN.
Yes, I will do so. Just let me know wnen to start.
[bobc – Wed Oct 18, 2017 10:07 am] –
I think practically speaking, USB and CAN can not be used in the same application on F103.
Maybe I understand you wrong, but did you see this example: http://stm32duino.com/viewtopic.php?f=1 … =90#p33946 ?
I’m able either to start my usual CAN script, or start USB as UART Serial port. Suggest how should I test using USB and CAN in one application?
[And_Ru – Fri Oct 20, 2017 8:33 am] –
I’m able either to start my usual CAN script, or start USB as UART Serial port.
That is a nice feature. But…
Does anybody need it? I doubt. I think one uses one or the other, but I cannot imagine any application in which USB and CAN should be alternatively used.
So in order to keep the original version used by many users safe and intact, I can only suggest to use a separate branch for CAN.
Fisrt, thanks you all guys that have done such a great work.
If anyone is still interested in this topic, I have done a library that uses the internal CAN controller.
https://github.com/jiauka/NMEA2000_stm32f1
It is working with a “Bluepil” stmF103c8 and a SN65HVD230 can driver, but it should work with any stm32Fxx MCU with maybe some minor change at the clock setting, I have to test wiht an STMF4xxx that I have laying around
NMEA2000_CAN.h need some tweaking to add the library
> #elif defined(STM32F103xB)||defined(STM32F103xB)
> #define USE_N2K_CAN USE_N2K_STM32F1xx_CAN
106a109,120
> #elif USE_N2K_CAN == USE_N2K_STM32F1xx_CAN
> // Use MBED devices
> #include <NMEA2000_stm32f1.h>
> tNMEA2000 &NMEA2000=*(new NMEA2000_stm32f1());
>
> #elif USE_N2K_CAN == USE_N2K_STM32F103_CAN
> // Use MBED devices
> #include <NMEA2000_mbed.h> // https://github.com/thomasonw/NMEA2000_mbed
> tNMEA2000 &NMEA2000=*(new tNMEA2000_mbed());
> tmbedStream serStream;
>
>
114,116c128,130
< #if defined(__STM32F1__) // Maple
< #include <MapleIntCompatibility.h>
< #endif
—
> #if defined(STM32F103xB) // Maple
> #include <NMEA2000_stm32f1.h>
> tNMEA2000 &NMEA2000=*(new NMEA2000_stm32f1());
117a132
> #endif
yours,
j.



(I’m sure its been discussed in detail before)
https://github.com/rogerclarkmelbourne/ … ardwareCAN.
I do, though, even when using the original unmodified patches, have interrupt-related problems that I’m not sure how to resolve — I’m embarrassed to say that the conversation from this point is going to reveal some shortcomings in my understanding of microcontrollers.
Specifically — when using IRQ mode (or, really, having any of the CAN interrupts — CANx->IER = (CAN_IER_FMPIE0 | CAN_IER_FMPIE1 | CAN_IER_TMEIE) — enabled), the moment any of those interrupts fire, the microcontroller appears to hang. That’s what inspired me to flesh out the polling mode described above. This doesn’t happen while debugging using an stlink, so I’m a little bit at a loss as to what I’m doing wrong and wonder if any of you folks have any input.
Given that I’m guessing it’s a problem in an ISR, I am very curious about is how the miscellaneous CAN_IER_FMPIE0/CAN_IER_TMEIE/etc derived interrupts are mapped to an actual ISR. I’ve had a look at page 673 in the manual (http://www.st.com/content/ccc/resource/ … 171190.pdf) and can see how those are mapped to a handful of interrupts in a general sense, but I’m not at all clear on what that might mean in Maple/Stm32duino as far as what those interrupts are called. I have, though, noticed the three interrupt functions at the bottom of can.c in the original supplied patches from Phonog —
uint8 __attribute__ ((interrupt)) CAN_RX0_IRQ_Handler(void)
{
if (can_active)
{
can_rx_copy_from_fifos();
}
return can_active; // return CAN active flag to USB handler
}
// Addition JMD: the messages stored in fifo1 must also trigger an interrupt.
void __irq_can_rx1(void)
{
CAN_RX0_IRQ_Handler() ;
}
void __attribute__ ((interrupt)) USB_HP_CAN_TX_IRQHandler(void)
{
if (can_active)
{
if (CAN1_BASE->TSR & CAN_TSR_RQCP0)
CAN1_BASE->TSR |= CAN_TSR_RQCP0; // reset request complete mbx 0
if (CAN1_BASE->TSR & CAN_TSR_RQCP1)
CAN1_BASE->TSR |= CAN_TSR_RQCP1; // reset request complete mbx 1
if (CAN1_BASE->TSR & CAN_TSR_RQCP2)
CAN1_BASE->TSR |= CAN_TSR_RQCP2; // reset request complete mbx 2
}
}
However, I am not sure which of them are used at all.
I use the CAN Bus Library, Works fine. But I have problems with the extended ID an filtering.
The filter works only with the standard ID. How can I use it for extended IDs?
That’s my code:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <HardwareCAN.h>
#define BPIN 0
#define SPIN 1
byte msgD0 ;
uint32_t lastSent = 0;
int count = 1;
int ledState = 0;
int extID = 1;
float cTemp;
float pressure;
union t_tag {byte b[4]; float tempVal;} t;
union p_tag {byte b[4]; float pressVal;} p;
// Instanciation of CAN interface
HardwareCAN canBus(CAN1_BASE);
CanMsg msg ;
// Set the LCD address to 0x3E for a 16 chars and 2 line display
LiquidCrystal_I2C lcd(0x3E, 20, 4);
void CANSetup(void)
{
CAN_STATUS Stat ;
// Initialize CAN module
canBus.map(CAN_GPIO_PB8_PB9);
Stat = canBus.begin(CAN_SPEED_1000, CAN_MODE_NORMAL); // set speed to 1000 kbps
CAN_ID_EXT;
lcd.setCursor(0, 1);
lcd.print("Status: ");
lcd.println(Stat);
canBus.filter(0, 0x00ffee00, 0x1fffffff); // filter don't work for ID 0x00FFEE00
canBus.filter(1, 0x3f, 0x1fffffff); // filter work for ID 0x00FFEE00
canBus.set_irq_mode(); // Use irq mode (recommended), so the handling of incoming messages
Stat = canBus.status();
if (Stat != CAN_OK) {
lcd.println("CAN initialization Failed");
/* Your own error processing here */ ; // Initialization failed
}
}
Can I found anywhere CAN BUS library and example for STM32F407?
I found a COIDE code for stm32discovery and it is works after changing. The board is changed to STM32F407VET6. The marked BLUE and RED leds are changed to PA6 and PA7 led. CAN pins are on PB8 and PB9, speed 100kb/s. I manage to upload onto the board. After the two leds are light. When I connect to 100kb/s CAN networks which push signal to the STM board, the two leds begin to blinking
I use sn65hvd230 CAN interface.
How can it implement into the generic or dunio repo?
The CAN library lacks proper information for use.
Regarding the filter mechanism, one must understand how the value passed as an argument for the identifier and the mask are used by the library.
It is because the identifier and mask registers should not be written directly with the value of the identifier. Instead, the identifier must be processed to match the bit allocation described in the figure below (refer to STM32 user’s manual RM0008 page 640, figure 229).
Method Argument [31:24] : [23:16] : [15:8] : [7:0]
Mapping STID[10:3] : STID[2:0] EXID[17:13] : EXID[12:5] : EXID[4:0] IDE RTR 0
Its too difficult for Me. I have a library for arduino stm32F103, it is work but I can not use it for STM32F407.
The linked “demo 59 CAN” example works in COIDE for STM32F407 (not use hal library).
Now Im trying to setup CAN module in DOIDE using hal library. The CUBEMX library has some info but not fully about CAN.
I did some can stuff with the UNO and car diagnostic hardware.
I bought on ebay some STM32F103C8T6 boards to use them as fast can communicator.
I connected a PCA82C250 transceiver to PB 8 and 9.
A USB TTL is connected to A9 A10.
The hardware is connected to some car modules on desk i know about that they are sending constantly.
Confirmed also with uno…
I just want to print can data out over the usb ttl.
Speed 125 Extended ID
I tested some librarys here for the board but lost the overview—
phonog compiles but crashes when i connect data lines to can bus
megadrifter has some errors in his filter the functions are declared different that i wasn’t able to reconstruct the filter function.
I found a third library in the last pages of the matching together discusion, it complies but also crashes…
It seems the interrupt crashes often within Serial.println i lose connection to chip.
Strange is also.
Serial1 is used in much librarys.
I only get output on Serial.
On the 3rd serial port i’m not able to program the stm32 right?
Can somebody offer a complete library he is sure about that it works on extended ids with usb ttl?
the CAN interface of the STM32F103 has a shared interrupt vector with the USB interface.
This is taken care of in the Arduino for STM32 kernel (at least in the version I have committed) and handled via weak identifier declarations in the library.
Please check whether the CAN interrupt vector is connected to the CAN interrupt service routine of the library.
i downloaded this library: https://github.com/Phonog/Arduino_STM32 … og-patch-1
and pasted all files over the arduino 1.85 installation i have done with download from ide.
So i should have all necessary files but the board crashes after connecting to can, maybe i have done something wrong with connecting the transceiver or the transceiver is broken but guess not
Further i did the same with this library https://github.com/megadrifter/Arduino_ … GMLAN-test
but here the filter setting in hardwarecan.cpp is wrong it should return with the output of some other filter function from can.c but the function is defined wrong, after uncommenting i nearly get the same result.
With some normal uno i’m able to receive data from the 125 extended id can bus so there is something on bus…
exit status 1
Error compiling for board Generic STM32F103C series
Specified folder/zip file does not contain a valid library.
What should I do to install the library (on an Windows system) ?
[Pito – Tue Jun 26, 2018 9:18 pm] –
Those links are not libraries, but entire stm32duino cores..
According to https://www.arduino.cc/en/guide/cores I need to use a board manager file, like:
https://github.com/stm32duino/boardmana … index.json
Or should I install the version with the CAN files in another way? If so, how?
Kind regards, Michel
Where can I find the latest version ? Phonog: is it here: https://github.com/Phonog/Arduino_STM32 … og-patch-1 ? Thanks.
Some of you might want to see code for working can here,
https://github.com/darkspr1te/OM127-reboot
Regards
darkspr1te
[Phono – Sat Mar 24, 2018 4:45 pm] –
For an extended identifier, it should be
( ( ( id & 0x7FF ) << 21 ) | ( ( id & 0x1FFFF800 ) >> 8 ) | 4 )
What I meant is that you must pass these expressions as th arguments to the call of the filter method. In your case, you might want to write
canBus.filter(0, ( ( id & 0x7FF ) << 21 ) | ( ( id & 0x1FFFF800 ) >> 8 ) | 4, 0xFFFFFFFF) ; // [Lukas – Sun May 27, 2018 10:15 pm] –
It seems the interrupt crashes often within Serial.println i lose connection to chip.
Hi!
Just for information, in my sketches I use
Serial1 = pins A9-A10
Serial2 = pins A2-A3
and this works good.
[michelkeijzers – Tue Jun 26, 2018 9:10 pm] –
Megadrifter (https://github.com/megadrifter/Arduino_ … GMLAN-test)
Please do not use this, I started to make some changes but now it seems to be abandoned.
If You have troubles installing the library, You can download the zip archive of installed Arduino IDE with working library inside.
https://cloud.mail.ru/public/Eqai/jAoXWVYnC (I made this snapshot for myself).
I have ported the HardwareCAN library to the newest core I took from the repository.
It crashed on initialization of the CAN interface.
I found out that the code of the initialisation in HardwareCAN.cpp
CAN_STATUS HardwareCAN::begin(CAN_SPEED speed, uint32 mode)
included a
Serial.end();
On earlier versions of the core, it used to work. Now it crashes. As a quick and dirty solution I commented it out.
In this state, my sketch works, but when its execution starts, my PC complains that an unrecognized USB device has been detected. It must be because the USB serial needs to be properly closed.
Who can tell me what is wrong now? What is the correct syntax for closing the USB serial interface?
Serial.end();
may be dangerous, if Serial is not defined at this time. I changed the code to
if ( Serial ) Serial.end() ;
and this cured the problem.
Please update your library accordingly.
Might you be so kind to give me a little hint about where i can find your ported can library so that i know where to apply you latest serial closing patch?
Your advice will be much appreciated!!
https://github.com/Phonog
I would like to start a project with 25 devices (STM32 Blue Pills) communicating through a CAN bus.
I need a CAN bus because I have pretty long cable distances (~ 2 meters) and SPI / I2C are very hard to get working in these conditions.
– Do I need external hardware or can I use the PB8/PB9 and PA11/PA12 pins of the Blue-Pill ? (which one should I use ?)
– What library should I use ? Raw CAN is fine (I don’t need CANopen for example)
– What is the state of this library ? Is there some missing functionality ?
I’ve read a little bit but I’m confused at what software is available and before starting anything I’d like to have more information ![]()
Thank you for you insights!
I don’t know if ST’s official core has high level support for CAN, you’d need to PM @fpiSTM and ask
You can always directly access the CAN hardware, but the problem is that its shared with USB, and by default the LibMaple core has USB support enabled unless you upload via hardware Serial
So I only need a CAN transceiver and the Blue Pill has the CAN controller (used through the HardwareCAN library) within the STM32?
I will do a complete tutorial (wiring + code) on how to communicate between 2 STM32 through a CAN bus when I get the MCP2551 chips and I get everything working.
[Vicolaships – Mon Feb 04, 2019 1:02 pm] –
I will do a complete tutorial (wiring + code) on how to communicate between 2 STM32 through a CAN bus when I get the MCP2551 chips and I get everything working.
I am planning to do a CAN bus project later in the year, so am looking forward to your tutorial. I have ordered some MCP2551 chips.
Now I have to find a project for them
[stevestrong – Thu Feb 07, 2019 10:02 am] –
I just received my 3 modules with MCP2515 +TJA1050, ordered from here: https://www.aliexpress.com/item/MCP2515 … 72090.html
Now I have to find a project for them![]()
Cool!
Why did you order such a module (CAN controller and CAN transceiver) if the Blue-Pill (and other STM32s) already have the CAN controller?
Why not order a TJA1050 or MCP2551 directly?
And the price for a transceiver alone is not much lower than a complete module, so why to bother with native CAN software?
Nevertheless, I still appreciate the effort to bring CAN to work on bp, just that I find much simpler to use a lib for MCP2515.
http://libopencm3.org/docs/latest/stm32 … fines.html

