Forum Rule: Always post complete source code & details to reproduce any issue!
Page 46 of 46 FirstFirst ... 36 44 45 46
Results 1,126 to 1,140 of 1140

Thread: FlexCAN_T4 - FlexCAN for Teensy 4

  1. #1126

    Quote Originally Posted by msadie View Post
    In your program, when you want to check if errors exist, you should be able to do something like this:
    Code:
    void loop() {
      ... some other code ...
    
      static uint32_t timeout = millis();
      if ( millis() - timeout > 1000 ) {  // Check for errors every 1000 ms
        CAN_error_t err;
        if CAN0.error(err, true) {
          // the "err" structure will be populated with the current errors.
          // Second argument set to true tells the error() function to ...
          // serial.print() the current errors. 
          ... some code to handle errors here ...
        }
      }
      ... some other code ...
    }
    worked like a champ thank you!

  2. #1127
    Junior Member
    Join Date
    Dec 2021
    Posts
    9
    Could you provide an example of how to configure and use filters with the FIFO?

  3. #1128
    Junior Member
    Join Date
    Dec 2021
    Posts
    9

    FIFO blocks mboxes

    Trying to use the FIFO blocks mboxes, both polled and interrupt driven.

    Initialization:

    Code:
    void MCOUSER_ResetCommunication(void){
      int i;
    
      gTimCnt = GTIMCNT; // Initialize global timer
      canbus1.begin(); // Must be first JGH
      canbus1.setMaxMB(16);
      canbus1.setMBFilter(REJECT_ALL);
      canbus1.setBaudRate(1000*BAUDRATE);
      for(i = 0; i < (NR_OF_RPDOS + 2); i++) { // NMT and SDO will use the first two boxes.
        canbus1.setMB((FLEXCAN_MAILBOX)i, RX, STD);
        if(i > 1){
        canbus1.onReceive((FLEXCAN_MAILBOX)i, canbus_isr); // Get all RPDOs via interrupt. 
        canbus1.enableMBInterrupt((FLEXCAN_MAILBOX)i); 
        }
      }
      for(; i < (NR_OF_RPDOS + NR_OF_TPDOS); i++) {
        canbus1.setMB((FLEXCAN_MAILBOX)i, TX, STD);
      }
      // For sync
      #ifdef SYNC
      canbus1.setMB((FLEXCAN_MAILBOX)i, RX, STD);
      canbus1.setMBFilter((FLEXCAN_MAILBOX)i, 0x080);
      canbus1.onReceive((FLEXCAN_MAILBOX)i, canbus_sync);
      canbus1.enableMBInterrupt((FLEXCAN_MAILBOX)i);
      #endif
      // BAUDRATE,Node_ID,HEARTRATE defined at the top of this file.  JGH
      MCO_Init(BAUDRATE,Node_ID,HEARTRATE);
    
      // Default base receive COBs are 0x200, 0x300, 0x400, and 0x500
      // Calling MCO_InitRPDO or MCO_InitTPDO with COB-ID 0 results in default
      // RPDO1, default ID (0x200+nodeID), 4 bytes
      MCO_InitRPDO(1, 0, 4, &target_speed); 
    
      // RPDO2, default ID (0x300+nodeID), 4 bytes
      MCO_InitRPDO(2, 0, 4, &acceleration);
      
      //BYTE PDO_NR,  WORD CAN_ID, WORD event_time, WORD inhibit_time, BYTE len, BYTE offset
      // TPDO1, default ID (0x180+nodeID), 100ms event, 5ms inhibit, 4 bytes
      // Transmit trigger: COS (change-of-state) with 250ms inhibit time
      MCO_InitTPDO(1, 0, 0, 5, 4, &control_word);    
    
      // TPDO2, default ID (0x280+nodeID), 100ms event, 5ms inhibit, 4 bytes
      // Transmit trigger: COS (change-of-state) with 250ms inhibit time
      MCO_InitTPDO(2, 0, 0, 5, 4, &status_word); 
    
      // TPDO3, default ID (0x380+nodeID), 100ms event, 5ms inhibit, 4 bytes
      // Transmit trigger: COS with 100ms inhibit time, but if there is no COS within
      // 1000ms, message gets triggered, too
      MCO_InitTPDO(3, 0, 0, 5, 4, &target_speed);
    
      // TPDO4, default ID (0x480+nodeID), 100ms event, 5ms inhibit, 4 bytes
      // Transmit trigger: COS with 100ms inhibit time, but if there is no COS within
      // 1000ms, message gets triggered, too
      MCO_InitTPDO(4, 0, 0, 5, 4, &acceleration);
    }
    
    
    /**************************************************************************
    DOES:    ISR for RPDO mailboxes. Writes message content to the correct PDO
             if the state_machine state permits. JGH
             
    RETURNS: nothing
    **************************************************************************/
    void canbus_isr(const CAN_message_t &msg) {
      int i;
      if(gMCOConfig.heartbeat_msg.BUF[0] != 5) return; // Only receive in operational state.
      i = mbox_to_RPDO[msg.mb]; // This tells us what RPDO this mbox goes with.
      if(gRPDOConfig[i].len != msg.len) return; // Not a valid message.  Should set an error. JGH
      memcpy(gRPDOConfig[i].offset, msg.buf, gRPDOConfig[i].len);
    }
    Added to experiment with the FIFO:

    Code:
      canbus1.enableFIFO();
      canbus1.disableFIFOInterrupt();
      canbus1.setFIFOFilter(REJECT_ALL);
      canbus1.enhanceFilter(FIFO);
      canbus1.setFIFOFilter(7, 0x123, STD);
    NMTs (id 0x000) and SDOs (id 0x607) are polled with this:
    Code:
    BYTE MCOHW_PullMessage(CAN_MSG *pReceiveBuf){
      // pointer to a single message sized buffer to hold the received message
     
      // variable declarations
      BYTE  Length;
      BYTE  i;
      CAN_message_t msg;
      if(canbus1.readMB(msg)){
        pReceiveBuf->ID = msg.id;
        pReceiveBuf->LEN = msg.len;
        // Read data bytes and write to buffer
        for (i=0; i < msg.len; i++){
          // copy bytes
          *(BYTE *)(pReceiveBuf->BUF+i) = msg.buf[i];
        }
        return (1);
      }
      else {
        // return 0, no message received
        return (0);
      }
    }
    RPDOs are handled by the ISR.

    The FIFO is read with this:
    Code:
      CAN_message_t mesg;
      if(canbus1.readFIFO(mesg)) {
        
        Serial.print("ID "); Serial.print(mesg.id, HEX);
        Serial.print(" Filter "); Serial.print(mesg.idhit, HEX);
        Serial.print(" LEN: "); Serial.print(mesg.len);
        Serial.print(" Buffer: ");
        for ( uint8_t i = 0; i < mesg.len; i++ ) {
          Serial.print(mesg.buf[i], HEX); Serial.print(" ");
        } Serial.println();
        
      }
    Everything works fine with the experimental FIFO stuff commented out. The FIFO code works as expected but when it's enabled all mboxes are blocked.
    Uncommenting just the FIFO initialization blocks the mboxes.
    Last edited by John Hasler; 01-30-2023 at 12:24 AM.

  4. #1129
    Junior Member
    Join Date
    Dec 2021
    Posts
    9
    It appears that the FIFO grabs the first 8 mboxes even if they are already allocated.

  5. #1130
    Quote Originally Posted by John Hasler View Post
    It appears that the FIFO grabs the first 8 mboxes even if they are already allocated.
    I'm not familiar enough with implementing filters to comment, but I can confirm the FlexCAN hardware reserves MB0-MB7 when FIFO is enabled.

  6. #1131
    Hi

    I have taken a lot of time to find a solution for my problem. I didn't find it.

    I use the following filter:

    Can.setFIFOFilter(0, 0x18DAF100, EXT);

    How is it possible to erase this filter to get all messages? I need this filter only for a short time.

    First - filter then all messages

    Thanx
    Gary

  7. #1132
    Gary, based on looking at the library, try:
    Code:
    Can.setFIFOFilter(Accept_All);
    Also, in case you weren't aware,
    Code:
    Can.MailboxStatus();
    is an easy way to see what's going on with the mailboxes and filters.

  8. #1133
    Hi msadie

    Thanks a lot. This is was im looking for. Perfect...

    Greetings
    Gary

  9. #1134
    Junior Member
    Join Date
    Feb 2023
    Posts
    1
    Hello,

    I am trying to run a Teensy 4.1 with two SN65HVD230 transceivers to talk to two can networks.

    I have no issues with getting CAN1 working on the 125k can network, but I cant get CAN2 to connect to my 83.3k network.

    I am using the Flexcan_T4 Library.

  10. #1135
    Junior Member
    Join Date
    Dec 2021
    Posts
    9

    error() sometimes returns true on transition between "Idle" and Receive"

    Example:

    FlexCAN State: Idle, FLT_CONF: Error Active
    In GetStatus gMCOHW_status = 1
    Receive errors = 0
    Transmit errors = 0
    error.ESR1 = 40080
    FlexCAN State: Receiving, FLT_CONF: Error Active
    In GetStatus gMCOHW_status = 1
    Receive errors = 0
    Transmit errors = 0
    error.ESR1 = 40008
    FlexCAN State: Idle, FLT_CONF: Error Active
    In GetStatus gMCOHW_status = 1
    Receive errors = 0
    Transmit errors = 0
    error.ESR1 = 40080

    gMCOHW_status = 1 means that the error variable contained no errors.

    I'm using a Teensy 3.6 running my heavily-hacked version of Microcanopen (no threads or interrupts: polling only). It is sending a TPDO every millisecond and receiving an RPDO sent by this script:

    while true; do sleep .001; cansend can0 307#ffffffff; done

    The bus master is canopend from Canopennode running under Linux on a pc connected to the Teensy by an 8devices USB to CAN converter.

    The relevant code from the Canopen implementation:

    Code:
    uint8_t MCOHW_GetStatus(void) {
      CAN_error_t error;
      bool cerr = false, erpa = false, boff = false;
      int state = CO_INTERFACE_ACTIVE; // Is this the right thing to do if no errors?
      gMCOHW_status &= INIT; // Clear CAN status but leave INIT state unchanged
      if(canbus1.error(error, PRINT_ERRORS)){ // PRINT_ERRORS is defined in mco.h
        // Evidently returns zero quickly if there are no errors
        cerr = error.BIT1_ERR || error.BIT0_ERR || error.ACK_ERR || error.CRC_ERR \
          || error.FRM_ERR || error.STF_ERR;
        
        if ((error.ESR1 & 0x30) == 0x0) { // Copied from FlexCAN_T4
          erpa = 0; // Error active
          state = CO_INTERFACE_ACTIVE;
    	}
        else if ((error.ESR1 & 0x30) == 0x1) { // Copied from FlexCAN_T4
          erpa = 1; // Error passive
          Serial.println("MCOHW_GetStatus: Error passive");
          state = CO_INTERFACE_LISTEN_ONLY;
        }
        else {
          boff = 1; // Bus off 
          Serial.println("MCOHW_GetStatus: Bus off");
          state = CO_INTERFACE_BUS_OFF;
        }
        gMCOHW_status |= cerr << 1;
        gMCOHW_status |= erpa << 2;
        gMCOHW_status |= error.TX_WRN << 3;
        gMCOHW_status |= error.RX_WRN << 4;
        gMCOHW_status |= boff << 7;
        Serial.print("In GetStatus gMCOHW_status = "); Serial.println(gMCOHW_status, BIN); // JGH debug
        Serial.print("Receive errors = "); Serial.println(error.RX_ERR_COUNTER);
        Serial.print("Transmit errors = "); Serial.println(error.TX_ERR_COUNTER);
        Serial.print("error.ESR1 = "); Serial.println(error.ESR1, HEX);
      }
      if((gMCOConfig.CANinterfaceState == CO_INTERFACE_BUS_OFF) && (state != CO_INTERFACE_BUS_OFF)) {
        Serial.println("MCOHW_GetStatus: Recovered from BUS_OFF");
        MCO_Handle_EMCY(CO_EMC_BUS_OFF_RECOVERED);
      }
      gMCOConfig.CANinterfaceState = state;
      return gMCOHW_status;
    }
    I'm using the FIFO with 8 filters allocated and with enhanceFilter(FIFO). The other mboxes are configured for transmit with TPDOs being sent via write(). It all works quite well but for this oddity.

    I can provide more code, of course, but the total is about 2100 lines.
    Last edited by John Hasler; 03-01-2023 at 01:01 AM.

  11. #1136
    So canbus1.error() returns true, but once the errors print, there are none?
    Am I understanding this correctly? If so, can you post the canbus.error() function?

  12. #1137
    Junior Member
    Join Date
    Dec 2021
    Posts
    9
    The error() function is part of FlexCAN_T4.

    Code:
    FCTP_FUNC bool FCTP_OPT::error(CAN_error_t &error, bool printDetails) {
      if ( !busESR1.size() ) return 0;
      NVIC_DISABLE_IRQ(nvicIrq);
      error.ESR1 = busESR1.read();
      error.ECR = busECR.read();
    
      if ( (error.ESR1 & 0x400C8) == 0x40080 ) strncpy((char*)error.state, "Idle", (sizeof(error.state) - 1));
      else if ( (error.ESR1 & 0x400C8) == 0x0 ) strncpy((char*)error.state, "Not synchronized to CAN bus", (sizeof(error.state) - 1));
      else if ( (error.ESR1 & 0x400C8) == 0x40040 ) strncpy((char*)error.state, "Transmitting", (sizeof(error.state) - 1));
      else if ( (error.ESR1 & 0x400C8) == 0x40008 ) strncpy((char*)error.state, "Receiving", (sizeof(error.state) - 1));
    
      error.BIT1_ERR = (error.ESR1 & (1UL << 15)) ? 1 : 0;
      error.BIT0_ERR = (error.ESR1 & (1UL << 14)) ? 1 : 0;
      error.ACK_ERR = (error.ESR1 & (1UL << 13)) ? 1 : 0;
      error.CRC_ERR = (error.ESR1 & (1UL << 12)) ? 1 : 0;
      error.FRM_ERR = (error.ESR1 & (1UL << 11)) ? 1 : 0;
      error.STF_ERR = (error.ESR1 & (1UL << 10)) ? 1 : 0;
      error.TX_WRN = (error.ESR1 & (1UL << 9)) ? 1 : 0;
      error.RX_WRN = (error.ESR1 & (1UL << 8)) ? 1 : 0;
    
      if ( (error.ESR1 & 0x30) == 0x0 ) strncpy((char*)error.FLT_CONF, "Error Active", (sizeof(error.FLT_CONF) - 1));
      else if ( (error.ESR1 & 0x30) == 0x1 ) strncpy((char*)error.FLT_CONF, "Error Passive", (sizeof(error.FLT_CONF) - 1));
      else strncpy((char*)error.FLT_CONF, "Bus off", (sizeof(error.FLT_CONF) - 1));
    
      error.RX_ERR_COUNTER = (uint8_t)(error.ECR >> 8);
      error.TX_ERR_COUNTER = (uint8_t)error.ECR;
    
      if ( printDetails ) printErrors(error);
      NVIC_ENABLE_IRQ(nvicIrq);
      return 1;
    }

  13. #1138
    Junior Member
    Join Date
    Feb 2023
    Posts
    2

    Smile Getting confused with this library

    Hi, I am programming two teensys 4.1 and I am using this library. While I was programming, I was trying to check if there are any CAN messages available in my loop() like this:
    void loop() {
    // Check if there are any CAN messages available
    if (can0.available()) {
    // Read the CAN message
    CAN_message_t msg;
    can0.read(msg);

    But there is no function "available()". Is there any function that does what I want to do or if I need to use another approach what would that be?

  14. #1139
    Senior Member
    Join Date
    Apr 2020
    Location
    DFW area in Texas
    Posts
    565
    Quote Originally Posted by jmlima44 View Post
    But there is no function "available()". Is there any function that does what I want to do or if I need to use another approach what would that be?
    In the Arduino IDE, take a look at the examples under File / Examples / Examples for Teensy 4.1 / FlexCAN_T4. One or more of those should get you started.

    Mark J Culross
    KD5RXT

  15. #1140
    Member profor's Avatar
    Join Date
    Jun 2015
    Location
    Stupava, Slovakia
    Posts
    27
    @jmlima44 mine works like this:

    Code:
    #include <FlexCAN_T4.h>
    CAN_message_t can_fwd_car;
    FlexCAN_T4<CAN2, RX_SIZE_32, TX_SIZE_32> can_master;
    
    void setup() {
      // put your setup code here, to run once:
      can_master.begin();
      can_master.setBaudRate(125000);
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
      
      if (can_master.read(can_fwd_car)) {
        
        //  do something with the data in can_fwd_car
      
      }
    
      //  rest of code
    
    }

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •