rogerclarkmelbourne / Arduino_STM32

Arduino STM32. Hardware files to support STM32 boards, on Arduino IDE 1.8.x including LeafLabs Maple and other generic STM32F103 boards
Other
2.5k stars 1.26k forks source link

HardwareCAN on F103RB #873

Closed svezauzeto closed 1 year ago

svezauzeto commented 2 years ago

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) ;  
}
svezauzeto commented 2 years 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.
}
rogerclarkmelbourne commented 1 year ago

Closing as problem has been resolved