Trying to get two MCP2515 working with the MCP2515_CAN driver.

sccoupesccoupe Posts: 118
edited 2019-02-12 - 02:23:09 in Propeller 1
I have a single propeller hooked up to two MCP2515/MCP2551 combinations on two different CAN networks. The network being the MCP2515 and a CAN analyzer to generate traffic. I tried to modify the driver file to run two MCP2515's but couldn't figure it out, so I just figured I'd run two different driver files, one via CAN1 and one via CAN2. Both drivers are the same aside from the SPI pins and the clock generator pins. All the drivers are set to do is when a CAN message arrives from any ID, it re-transmits the data. So CAN1 re-transmits on CAN ID 0x222 and CAN2 re-transmitts on CAN ID 0x333. My CAN analyzer is generating traffic with CAN ID 0x111. So, running DUAL_MCP2515_NEW, if I only run one at a time, everything works as it should. If I try to run both at the same time, then only the first one that is called is running correctly. The second never does. Its probably each driver stepping on each other, but I did try running one as PASM and the second as SPIN and no luck there either. By the way, the CAN analyzer is only connected to one network at a time. I'm just swapping back and forth to see if data is re-transmitted.

Any ideas?

Comments

  • Your problem is that you're trying to execute a cognew across objects
    PUB main
      waitcnt(cnt + clkfreq)
      cognew(CAN1.main, @stack[0])  ' <- this is treated a jump to the CAN1.main method
      CAN2.main                     ' <- This never executes because the cog is looping around inside CAN1.main 
      repeat
    
    Instead, you need to allocate some stack space and create a start method in your CAN1 object.
    PUB start
      cognew(main,@stack)
    
    PUB main | frame
      InitSPI(_CLK,_MISO,_MOSI,_CS,SPIN,0)
      UseOscillator(26)                                     ' Use Prop pin 26 to generate an oscillator for the MCP2515
      SendCommand(CMD_RESET)
      SetCanbusBitrate(500_000)                             ' Set the BaudRatePrescaler for 500Kbps operation
      SetMode(MODE_NORMAL)
      repeat
        if frame := ReadRxBuffer(@rx_buffer)
          LoadTxBuffer(0,$222,8,rx_buffer[5],rx_buffer[6],rx_buffer[7],rx_buffer[8],rx_buffer[9],rx_buffer[10],rx_buffer[11],rx_buffer[12])
          SendTxBuffer(0)
    
    The call to CAN2.main is fine, provided that you don't need to return to your top-level object.

    That said, I think you're making this way too complicated. Try this instead:
    CON
      _clkmode = xtal1 + pll16x
      _xinfreq = 5_000_000
    
      CAN1_CLK  = 10
      CAN1_MISO = 3
      CAN1_MOSI = 4 
      CAN1_CS   = 27
      CAN1_OSC  = 26
    
      CAN2_CLK  = 17
      CAN2_MISO = 19
      CAN2_MOSI = 18
      CAN2_CS   = 20
      CAN2_OSC  = 0
    
    VAR
      byte  rx_buffer[13]          
    
    OBJ
      CAN1  : "MCP2515 driver"
      CAN2  : "MCP2515 driver"
    
    PUB Main 
      CAN1.InitSPI(CAN1_CLK,CAN1_MISO,CAN1_MOSI,CAN1_CS,CAN1#SPIN,0)
      CAN1.UseOscillator(CAN1_OSC)
      CAN1.SendCommand(CAN1#CMD_RESET)
      CAN1.SetCanbusBitrate(500_000)                       
    
      CAN2.InitSPI(CAN2_CLK,CAN2_MISO,CAN2_MOSI,CAN2_CS,CAN2#SPIN,0)
      CAN2.UseOscillator(CAN2_OSC)
      CAN2.SendCommand(CAN2#CMD_RESET)
      CAN2.SetCanbusBitrate(500_000)                       
    
      repeat
        if CAN1.ReadRxBuffer(@rx_buffer)                                           
          CAN1.LoadTxBuffer(0,$222,8,rx_buffer[5],rx_buffer[6],rx_buffer[7],rx_buffer[8],rx_buffer[9],rx_buffer[10],rx_buffer[11],rx_buffer[12])
          CAN1.SendTxBuffer(0)
        if CAN2.ReadRxBuffer(@rx_buffer)
          CAN2.LoadTxBuffer(0,$333,8,rx_buffer[5],rx_buffer[6],rx_buffer[7],rx_buffer[8],rx_buffer[9],rx_buffer[10],rx_buffer[11],rx_buffer[12])
          CAN2.SendTxBuffer(0)
    
  • sccoupesccoupe Posts: 118
    edited 2019-02-13 - 15:22:05
    Thanks Chris. I see what you mean here. There are still some problems though, so I dropped this all down to one CAN bus and one processor. The attached program runs fine and each time a package comes in, the prop sends the message back out ok. However as soon as I un-comment the stack, the prop stops sending out CAN messages. The 'TEST' serial message goes out ok each time it runs 'DemoReader'. The CAN analyzer is not generating bus error's, so the MCP2515 is sending ack's ok. I've tried larger and smaller stack sizes, but it still stops the prop response CAN messages.
  • If I run InitSPI with SPIN, everything runs fine with the stacks and extra processors, two CAN busses etc. But when I InitSPI with PASM and use any kind of stack (long stack[100]), then things go haywire. Will continue testing, but the SPIN SPI is too slow when CAN bus utilization rises.
  • sccoupesccoupe Posts: 118
    edited 2019-02-13 - 17:13:16
    GOT IT! Had to call the stack var before the SPI vars so that the order stayed correct for the PASM driver after compiling.

    Thanks!!!
Sign In or Register to comment.