cancel
Showing results for 
Search instead for 
Did you mean: 

I am a thesis student and I have to build a bare-metal application to make the two CAN subsystems on SPC58NN84x MCU communicate, starting from bare-metal application for CAN testing on implemented by default on SPC5 studio, how can I do this?

ZMoha.1
Associate II

I have used the default test bare-metal application for the testing the can in SPC5 studio stopped the loopback, swap the RX ID filters in the configurator, and tried to send using one can subsystem and receive by the  other but it keeps stuck in this for loop ( if (return value != CAN_MSG_OK){ for ( ; ; ) {}; )}

please let me know how to fix this or if there is a step or another way to follow other than using this bare-metal application.

screenshot of the configurations are attached

---------------------------------------------------------------------------------------------------------------------------------------

This is the code:

-----------------------

/****************************************************************************

*

* Copyright © 2015-2019 STMicroelectronics - All Rights Reserved

*

* License terms: STMicroelectronics Proprietary in accordance with licensing

* terms SLA0089 at www.st.com.

* THIS SOFTWARE IS DISTRIBUTED "AS IS," AND ALL WARRANTIES ARE DISCLAIMED, 

* INCLUDING MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

*

* EVALUATION ONLY – NOT FOR USE IN PRODUCTION

*****************************************************************************/

/* Inclusion of the main header files of all the imported components in the

 order specified in the application wizard. The file is generated

 automatically.*/

#include "components.h"

#include "can_lld_cfg.h"

static uint32_t counter;

uint8_t CANDRX_check;

//uint8_t CAND7RX_check = 0x46;

//CANRxFrame check;

/* mcanconf is configured to use also CANFD operation

 * uncommenting following define will allow test application

 * to send and recevie CANFD frames on MCAN SUB 0 CAN 1*/

//#define USE_CANFD

/* comment this define and remove the callback field

 * in the configurator if you want to use the can_lld_receive

 * instead of the read callback routines

 */

#define USE_READ_CALLBACK

/* Use this define and remove the callback field

 * in the configurator if you want to use the can_lld_receive

 * instead of the read callback routines

 */

//#define USE_READ_FUNCTION

/**

 * MCAN Error callbacks

 *

 * canp   pointer to the @p CAN Driver object triggering the error

 * psr    Protocol Status Register logging the error

 *

 * If error callback is defined , this function will be called when following errors occur:

 * - WDI: Watchdog Interrupt

 * - BO:  BusOff

 * - EW:  Warning Status

 * - EP:  Error Passive

 * - ELO: Error Logging Overflow

 * - BEU: Bit Error Uncorrected

 * - BEC: Bit Error Corrected

 * - TOO: Timeout

 * - ARA: Access to reserved address

 * - PED: Protocol Error In Data Phase

 * - PEA: Protocol error in Arbitration Phase

 * - MRAF: Message RAM access Failure

 *

 * MCAN_ERROR_MASK defined in platform.h contains bit map for these errors. refer to RM

 * if you want to change errors trapped.

 */

void mcanconf_errorcb(CANDriver *canp, uint32_t psr){

 /* write error management code here */

 (void)canp;

 (void)psr;

}

#if defined USE_READ_CALLBACK

void mcanconf_rxreceive(uint32_t msgbuf, CANRxFrame crfp) {

#ifdef USE_CANFD

 if (crfp.OPERATION == CAN_OP_CANFD) {

#endif

  if (crfp.ID == 0x7f0U) {

   if (crfp.data32[1] == counter) {

    pal_lld_togglepad(PORT_A, LED_D2);

    CANDRX_check= crfp.data32[1];

    sd_lld_write(&SD1, &CANDRX_check, 1);

   };

  }

#ifdef USE_CANFD

 }

#endif

 (void)msgbuf;

}

void mcanconf1_rxreceive(uint32_t msgbuf, CANRxFrame crfp) {

 if (crfp.ID == 0x8901234UL) {

  if (crfp.data32[1] == counter) {

   pal_lld_togglepad(PORT_A, LED_D3);

   CANDRX_check= crfp.data32[1];

   sd_lld_write(&SD1, &CANDRX_check, 1);

  }

 }

 (void)msgbuf;

}

#endif

/*

 * Application entry point.

 */

int main(void) {

 CANTxFrame txf, txf1;

 uint32_t returnvalue;

 /* Initialization of all the imported components in the order specified in

  the application wizard. The function is generated automatically.*/

 componentsInit();

 /* Enable Interrupts */

 irqIsrEnable();

 /* Start Serial Driver */

 sd_lld_start(&SD1, NULL);

 can_lld_start(&CAND3, &can_config_mcanconf); /*MCAN SUB 0 CAN 1*/ /////////////////////////

 can_lld_start(&CAND7, &can_config_mcanconf1); /*MCAN SUB 1 CAN 1*/ ////////////////////////

 /* prepare frame to be transmitted on MCAN SUB 0 CAN 1*/ /*Defines the frame sent*/

 txf.TYPE = CAN_ID_STD;

 txf.ID = 0x7f0U;

 txf.DLC = 8U;

 txf.data32[0] = 0xDDEEFFAAUL;

#ifdef USE_CANFD

 txf.OPERATION = CAN_OP_CANFD;

#endif

 /* prepare frame to be transmitted on MCAN SUB 1 CAN 1*/ /*Defines the frame sent*/

 txf1.TYPE = CAN_ID_XTD;

 txf1.ID = 0x8901234;

 txf1.DLC = 8U;

 txf1.data32[0] = 0xAABBCCDDUL;

 counter = 0UL;

 /* Application main loop.*/

 for (;;) {

  txf.data32[1] = counter;

  txf1.data32[1] = counter;

  returnvalue = can_lld_transmit(&CAND7, CAN_ANY_TXBUFFER, &txf);

  osalThreadDelayMilliseconds(1);

  if (returnvalue != CAN_MSG_OK) {

   for (;;) {

   }

  }

  returnvalue = can_lld_transmit(&CAND3, CAN_ANY_TXBUFFER, &txf1);

  osalThreadDelayMilliseconds(1);

  if (returnvalue != CAN_MSG_OK) {

   for (;;) {

   }

  }

#if defined  USE_READ_FUNCTION

  {

   CANRxFrame rxf;

   returnvalue = can_lld_receive(&CAND2, CAN_ANY_RXBUFFER, &rxf);

#ifdef USE_CANFD

   if (rxf.OPERATION == CAN_OP_CANFD) {

#endif

    if (returnvalue == CAN_MSG_OK) {

     if (rxf.ID == 0x7f0U) {

      if (rxf.data32[1] == counter) {

       pal_lld_togglepad(PORT_A, LED_D2);

      }

     }

    }

#ifdef USE_CANFD

   }

#endif

   returnvalue = can_lld_receive(&CAND7, CAN_ANY_RXBUFFER, &rxf);

   if (rxf.ID == 0x8901234UL) {

    if (rxf.data32[1] == counter) {

     pal_lld_togglepad(PORT_A, LED_D3);

    }

   }

  }

#endif

  osalThreadDelayMilliseconds(250);

  counter++;

 }

}

5 REPLIES 5
RMalc.1
Associate II

CAN_MSG_OK . But which subsystem (node) 0 or 1 said so?​ Also transmitting both nodes at the same time so the lower priority message has to yield. Try not sending both at the same time.

Erwan YVIN
ST Employee

Yes , could you add some tempos between the 2 transmissions

You should use PLS Debugger in order to check why your 2nd CAN Frame is not sent.

Best regards

Erwan

I was using both, however, I tried sending only one message from one can and receiving it through both CANs, so that I can have one sender and two receivers but both receivers receive only the first version of the TX buffer, and whenever I update it doesn't keep up with this update unlike what happens in the LOOPBACK mode.

Note: Each CAN have a different subsystem but they share the same configurations and both are in NO LOOPBACK mode

The part of the code that is responsible for assigning the update to the first TX buffer is this:

-----------------------------------------------------------------------------------------------------------------------------------------

 /* send message using dedicated TX buffers */

 else {

  if (canp->config->tx_mode == CAN_FIFO_TXBUFFER || canp->config->tx_mode == CAN_QUEUE_TXBUFFER) {

   return CAN_TXMODE_NOT_SUPPORTED;

  }

  /* if CAN_ANY_TXBUFFER serach the first tx buffer free*/

  if (msgbuf == CAN_ANY_TXBUFFER) {

   for (count = 0; count < canp->config->num_of_tx_buffers; count++) {

    if (((canp->mcan->TXBRP.R) & (1UL << count)) == 0U) {

     txbuffer = (uint8_t)count;

     break;

    }

   }

  }

  /* else check if msgbox if free to transmit */

  else {

   if (((canp->mcan->TXBRP.R) & (1UL << msgbuf)) == 0U) {

    txbuffer = (uint8_t)msgbuf;

   }

  }

 }

 /*if txbuffer value is not assigned No tx buffer available */

 if (txbuffer == 0xFFU) {

  return CAN_MSG_WAIT;

 }

 else {

  /*Write Tx Buffer */

  can_lld_writeTxBuffer(canp, txbuffer, ctfp);

  /* send message */

  canp->mcan->TXBAR.R = (1UL << txbuffer);

 }

 return CAN_MSG_OK;

However, if I used the EXTERNAL LOOPBACK configuration they both receive correctly

I was using both, however, I tried sending only one message from one can and receiving it through both CANs, so that I can have one sender and two receivers but both receivers receive only the first version of the TX buffer, and whenever I update it doesn't keep up with this update unlike what happens in the LOOPBACK mode.

Note: Each CAN have a different subsystem but they share the same configurations and both are in NO LOOPBACK mode

However, if I used the EXTERNAL LOOPBACK configuration they both receive correctly

The part of the code that is responsible for assigning the update to the first TX buffer is this:

-----------------------------------------------------------------------------------------------------------------------------------------

 /* send message using dedicated TX buffers */

 else {

  if (canp->config->tx_mode == CAN_FIFO_TXBUFFER || canp->config->tx_mode == CAN_QUEUE_TXBUFFER) {

   return CAN_TXMODE_NOT_SUPPORTED;

  }

  /* if CAN_ANY_TXBUFFER serach the first tx buffer free*/

  if (msgbuf == CAN_ANY_TXBUFFER) {

   for (count = 0; count < canp->config->num_of_tx_buffers; count++) {

    if (((canp->mcan->TXBRP.R) & (1UL << count)) == 0U) {

     txbuffer = (uint8_t)count;

     break;

    }

   }

  }

  /* else check if msgbox if free to transmit */

  else {

   if (((canp->mcan->TXBRP.R) & (1UL << msgbuf)) == 0U) {

    txbuffer = (uint8_t)msgbuf;

   }

  }

 }

 /*if txbuffer value is not assigned No tx buffer available */

 if (txbuffer == 0xFFU) {

  return CAN_MSG_WAIT;

 }

 else {

  /*Write Tx Buffer */

  can_lld_writeTxBuffer(canp, txbuffer, ctfp);

  /* send message */

  canp->mcan->TXBAR.R = (1UL << txbuffer);

 }

 return CAN_MSG_OK;