Arduino_STM32
Arduino_STM32 copied to clipboard
HardwareCAN on F103RB
Using coddingtonbear/Arduino_STM32/tree/HardwareCAN) fork as core.
Here is simple explanation of the problem: I have multiple devices on bus, some of them are ESP32(receiving and sending is working), STM32F1(only sending packet is working).
Same Can init and setup is used for sending and receiving example, just receiving example is not working.
Here is receiving code for stm:
#include <HardwareCAN.h>
HardwareCAN canBus(CAN1_BASE);
void CANSetup(void){
CAN_STATUS Stat ;
canBus.map(CAN_GPIO_PA11_PA12); // PA11-CRX/ PA12-CTX
Stat = canBus.begin(CAN_SPEED_500, CAN_MODE_NORMAL );
canBus.filter(0, 0, 0);
canBus.set_irq_mode(); // tried with and without irq, same result
Stat = canBus.status();
if (Stat != CAN_OK) {
/* Your own error processing here */ ; // Initialization failed
}
}
void ProcessMessages(void){
CanMsg *r_msg;
if ((r_msg = canBus.recv()) != NULL){ //CODE DOESN'T EVER GO INTO THIS
Serial2.print(r_msg->ID);
Serial2.print("#");
Serial2.print(r_msg->Data[0]);
Serial2.print(".");
Serial2.print(r_msg->Data[1]);
Serial2.print(".");
Serial2.print(r_msg->Data[2]);
Serial2.print(".");
Serial2.print(r_msg->Data[3]);
Serial2.print(".");
Serial2.print(r_msg->Data[4]);
Serial2.print(".");
Serial2.print(r_msg->Data[5]);
Serial2.print(".");
Serial2.print(r_msg->Data[6]);
Serial2.print(".");
Serial2.println(r_msg->Data[7]);
canBus.free(); // Remove processed message from buffer, whatever the identifier
}
}
void setup() {
*((uint32_t*)0x40005c40) = 3 ; // USB_CNTR
*((uint32_t*)0x40005c44) = 0 ; // USB_ISTR
CANSetup() ;
Serial2.begin(115200); //PA9 UART1 RX //PA10 UART1 TX
Serial2.println("Serial2");
}
void loop() {
ProcessMessages() ;
delay(20) ;
}
Just use lowlevel functions, and receiving packets is working.
#include <HardwareCAN.h>
#define STM32_CAN_RIR_IDE (1U << 2U) // Bit 2: Identifier Extension
#define CAN_STD_ID_MASK 0x000007FFU
typedef enum {STANDARD_FORMAT = 0, EXTENDED_FORMAT} CAN_FORMAT;
typedef enum {DATA_FRAME = 0, REMOTE_FRAME} CAN_FRAME;
typedef struct
{
uint32_t id; /* 29 bit identifier */
uint8_t data[8]; /* Data field */
uint8_t len; /* Length of data field in bytes */
uint8_t ch; /* Object channel(Not use) */
uint8_t format; /* 0 - STANDARD, 1- EXTENDED IDENTIFIER */
uint8_t type; /* 0 - DATA FRAME, 1 - REMOTE FRAME */
} CAN_msg_t;
HardwareCAN canBus(CAN1_BASE);
void CANSetup(void)
{
CAN_STATUS Stat ;
canBus.map(CAN_GPIO_PA11_PA12); // PA11-CRX/ PA12-CTX
Stat = canBus.begin(CAN_SPEED_500, CAN_MODE_NORMAL);
canBus.filter(0, 0, 0);
// canBus.set_irq_mode(); // OR USE canBus.set_poll_mode();
Stat = canBus.status();
if (Stat != CAN_OK) {
}
}
void setup() {
*((uint32_t*)0x40005c40) = 3 ; // USB_CNTR
*((uint32_t*)0x40005c44) = 0 ; // USB_ISTR
CANSetup() ; // Initialize the CAN module and prepare the message structures.
Serial2.begin(115200); //PA9 UART1 RX //PA10 UART1 TX
Serial2.println("Serial2 --> HWSerial2");
}
void loop() {
ProcessMessages() ; // Process all incoming messages, update local variables accordingly
}
void ProcessMessages(){
CAN_msg_t CAN_RX_msg;
if(CANMsgAvail()) {
CANReceive(&CAN_RX_msg);
}
}
uint8_t CANMsgAvail(void){
return CAN1_BASE->RF0R & 0x3UL; // Check for pending FIFO 0 messages
}
void CANReceive(CAN_msg_t* CAN_rx_msg){
uint32_t id = CAN1_BASE->sFIFOMailBox[0].RIR;
if ((id & STM32_CAN_RIR_IDE) == 0) { // Standard frame format
CAN_rx_msg->format = STANDARD_FORMAT;;
CAN_rx_msg->id = (CAN_STD_ID_MASK & (id >> 21U));
CAN_rx_msg->len = (CAN1_BASE->sFIFOMailBox[0].RDTR) & 0xFUL;
CAN_rx_msg->data[0] = 0xFFUL & CAN1_BASE->sFIFOMailBox[0].RDLR;
CAN_rx_msg->data[1] = 0xFFUL & (CAN1_BASE->sFIFOMailBox[0].RDLR >> 8);
CAN_rx_msg->data[2] = 0xFFUL & (CAN1_BASE->sFIFOMailBox[0].RDLR >> 16);
CAN_rx_msg->data[3] = 0xFFUL & (CAN1_BASE->sFIFOMailBox[0].RDLR >> 24);
CAN_rx_msg->data[4] = 0xFFUL & CAN1_BASE->sFIFOMailBox[0].RDHR;
CAN_rx_msg->data[5] = 0xFFUL & (CAN1_BASE->sFIFOMailBox[0].RDHR >> 8);
CAN_rx_msg->data[6] = 0xFFUL & (CAN1_BASE->sFIFOMailBox[0].RDHR >> 16);
CAN_rx_msg->data[7] = 0xFFUL & (CAN1_BASE->sFIFOMailBox[0].RDHR >> 24);
Serial2.print("ID ");Serial2.println(CAN_rx_msg->id,DEC);
Serial2.print("D0 ");Serial2.println(CAN_rx_msg->data[0],DEC);
Serial2.print("DLC ");Serial2.println(CAN_rx_msg->len,DEC);
Serial2.println("_______");
}
CAN1_BASE->RF0R |= 0x20UL; //Release FIFO 0 output mailbox. Make the next incoming message available.
}
Closing as problem has been resolved