Arduino_STM32 icon indicating copy to clipboard operation
Arduino_STM32 copied to clipboard

HardwareCAN on F103RB

Open svezauzeto opened this issue 2 years ago • 1 comments

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 avatar Mar 17 '22 17:03 svezauzeto

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.
}

svezauzeto avatar Mar 17 '22 23:03 svezauzeto

Closing as problem has been resolved

rogerclarkmelbourne avatar Sep 16 '22 23:09 rogerclarkmelbourne