Closed svezauzeto closed 1 year ago
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
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: