This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Senseless send CAN frame

Hi everyone, 

I want to develop my CAN driver for the UT32M0R500 micrcontroller. I send a CAN frame on the principal bus. I should get the the send frame signal on the Tx pin.

However, when I tested it, it produced the the following result.

The green signal is the generated signal on the Tx pin.

I tried to modify my code and I tried to add a transciever to look at the CAN HIGH, but nothing has changed (the transciever return a 0 signal... It seems that it does not understand the Tx input)

So I decided to inspire my code from the example provided by CAES : it produces the same thing.

I directly tested the exemple provided by CAES :  it produces the same thing.

Then, I wrote the simpliest test as possible that follows : 

MAIN.C

#include "typesGeneral.h"
#include "canRegisterTypes.h"


#define C_CAN_MODE_RESET                            0x01

#define C_CAN_ACCEPTANCE_CODE_RESET_VALUE           0x00 
#define C_CAN_ACCEPTANCE_MASK_RESET_VALUE           0x00

#define C_CAN_COMMAND_START_TRANSMIT                0x01

#define C_CAN_SJW_SHIFT_LEFT                         (6)
#define C_CAN_SAM_SHIFT_LEFT                         (7)
#define C_CAN_TSEG2_SHIFT_LEFT                       (4)

#define C_CAN_TXID_1_ID_SHIFT_RIGHT                  (3)
#define C_CAN_TXID_2_ID_SHIFT_LEFT                   (5)   
																						         
#define C_CAN_SFF_ID_1_TX_SHIFT_RIGHT                (3) 
#define C_CAN_SFF_ID_2_TX_SHIFT_LEFT                 (5) 

/* ------------------------------------------------------------------------- */
// Nominal CAN base
/* ------------------------------------------------------------------------- */

volatile static t_canRegisters *s_canNominal   = (t_canRegisters *) 0x40023000;

typedef struct
{
	// Bus timing 1
	t_int8u          syncJumpWidth : 2;
    t_int8u          baudRatePreScalar : 6;
    // Bus timing 2
	t_int8u          sampleMode   : 1;
	t_int8u          timeSegment2 : 3;
	t_int8u          timeSegment1 : 4;
	// Hardware Address
    t_int8u          hardwareAddress;
} t_canInitData;


/* ------------------------------------------------------------------------- */
// MAIN
/* ------------------------------------------------------------------------- */


int main()
{		
	volatile t_canRegisters *l_can;
	t_canInitData l_canInitData;
	
	/* Init of the timings */
	l_canInitData.syncJumpWidth = 0;
	l_canInitData.baudRatePreScalar= 24;
    l_canInitData.sampleMode = 0;
	l_canInitData.timeSegment1 = 4;
	l_canInitData.timeSegment2 = 3;
	l_canInitData.hardwareAddress = 0xAA;

	/* Choose the nominal CAN*/
	l_can = s_canNominal;
	
	/* Enter reset mode */
	l_can->can.control = C_CAN_MODE_RESET;
	l_can->can.command = 0x00;

    /* Init acceptance masks */
    l_can->can.acceptCode = C_CAN_ACCEPTANCE_CODE_RESET_VALUE;
    l_can->can.acceptMask = C_CAN_ACCEPTANCE_MASK_RESET_VALUE;
	
	/* Init of the timings */
	l_can->can.busTiming_0 = (l_canInitData.syncJumpWidth<<C_CAN_SJW_SHIFT_LEFT) | (l_canInitData.baudRatePreScalar);
    l_can->can.busTiming_1 = (l_canInitData.sampleMode<<C_CAN_SAM_SHIFT_LEFT) | (l_canInitData.timeSegment2<<C_CAN_TSEG2_SHIFT_LEFT) |(l_canInitData.timeSegment1);
	
	// Set operating mode
	l_can->can.control &= (~C_CAN_MODE_RESET);

	/* Set ID, RTR and DLC in the register */
	l_can->can.TX_ID_1 = 0x00;
	l_can->can.TX_ID_2 = 0x08;
	
	/* Change the data in the TX buffer */
	l_can->can.TX_data[0] = 1;
	l_can->can.TX_data[1] = 2;
	l_can->can.TX_data[2] = 3;
	l_can->can.TX_data[3] = 4;
	l_can->can.TX_data[4] = 5;
	l_can->can.TX_data[5] = 6;
	l_can->can.TX_data[6] = 7;
	l_can->can.TX_data[7] = 8;

	while(1)
	{  
		// Set operating mode
	    l_can->can.control &= (~C_CAN_MODE_RESET);
		
		/* Start can transmission*/
		l_can->can.command = C_CAN_COMMAND_START_TRANSMIT;

	}
	
	return(0);
}

TYPESGENERAL.H

/**
 * @file        typesGeneral.h
 *
 * @brief       Native types and main constants redefinition
 *
 * @details     This file redefines the CPU architecture native types and the main constants
 *              (True / False / Null pointer) to be used in the whole project.
 *
 * @addtogroup  generalities
 * @{
 */

#ifndef INC_TYPES_GENERAL_H
#define INC_TYPES_GENERAL_H

/* ------------------------------------------------------------------------- */
// CONSTANTS DEFINITION
/* ------------------------------------------------------------------------- */

/**
 * @brief   Definition of the TRUE value
 */
#ifndef C_TRUE
#define C_TRUE (1 == 1)
#endif

/**
 * @brief   Definition of the FALSE value
 */
#ifndef C_FALSE
#define C_FALSE (!C_TRUE)
#endif

/**
 * @brief   Definition of the NULL-pointer value
 */
#ifndef C_NULL
#define C_NULL ((void*) 0L)
#endif

/* ------------------------------------------------------------------------- */
// TYPES DEFINITION
/* ------------------------------------------------------------------------- */

/**
 * @brief   8-bit signed integer
 */
typedef signed char         t_int8;

/**
 * @brief   8-bit unsigned integer
 */
typedef unsigned char       t_int8u;

/**
 * @brief   16-bit signed integer
 */
typedef signed short        t_int16;

/**
 * @brief   16-bit unsigned integer
 */
typedef unsigned short      t_int16u;

/**
 * @brief   32-bit signed integer
 */
typedef signed long          t_int32;

/**
 * @brief   32-bit unsigned integer
 */
typedef unsigned long        t_int32u;

/**
 * @brief   64-bit unsigned integer
 */
typedef unsigned long long   t_int64u;

/**
 * @brief   Boolean type
 */
typedef unsigned short        t_bool;


#endif /* INC_TYPES_GENERAL_H */

/** @}*/

CANREGISTERTYPES.H

/**
 * @file        canRegisterTypes.h
 *
 * @brief       Define all the registers used by the CAN peripheral.
 *
 * @addtogroup  can
 * @{
 */
 #ifndef INC_CAN_TYPES_DEF_H
 #define INC_CAN_TYPES_DEF_H
/* ------------------------------------------------------------------------- */
// FILE INCLUSION
/* ------------------------------------------------------------------------- */

#include "typesGeneral.h"

 /* ------------------------------------------------------------------------- */
// PRIVATE CONSTANTS DEFINITION
/* ------------------------------------------------------------------------- */

#define C_CAN_BUF_SIZE 8

/* ------------------------------------------------------------------------- */
// TYPES DEFINITION
/* ------------------------------------------------------------------------- */
/*------------------------ BASI-CAN -----------------------*/
typedef struct
{
   t_int8u  control;                  /*!< Offset: 0x00: Control Register                         (R/W) */
   t_int8u  command;                  /*!<         0x01: Command                                  ( /W) */
   t_int8u  status;                   /*!<         0x02: Status                                   (R/ ) */
   t_int8u  interrupt;                /*!<         0x03: Interrupt (reset on read, except bit0)   (R/ ) */
   t_int8u  acceptCode;               /*!<         0x04: Acceptance Code: RESET MODE ONLY         (R/W) */
   t_int8u  acceptMask;               /*!<         0x05: Acceptance Mask: RESET MODE ONLY         (R/W) */
   t_int8u  busTiming_0;              /*!<         0x06: Bus Timing 0: RESET MODE ONLY            (R/W) */
   t_int8u  busTiming_1;              /*!<         0x07: Bus Timing 1: RESET MODE ONLY            (R/W) */
   t_int8u  reserved_0;               /*!<         0x08: reserved                                 (R/ ) */
   t_int8u  reserved_1;               /*!<         0x09: reserved                                 (R/ ) */
   t_int8u  TX_ID_1;                  /*!<         0x0A: Transmit ID 1: OPERATE MODE ONLY         (R/W) */
   t_int8u  TX_ID_2;                  /*!<         0x0B: Transmit ID 2: OPERATE MODE ONLY         (R/W) */
   t_int8u  TX_data[C_CAN_BUF_SIZE];  /*!<   0x0C..0x13: Transmit Data Regs: OPERATE MODE ONLY    (R/W) */
   t_int8u  RX_ID_1;                  /*!<         0x14: Receive ID 1                             (R/ ) */
   t_int8u  RX_ID_2;                  /*!<         0x15: Receive ID 2                             (R/ ) */
   t_int8u  RX_data[C_CAN_BUF_SIZE];  /*!<   0x16..0x1D: Receive Data Regs                        (R/ ) */
   t_int8u  reserved_2;               /*!<         0x1E: reserved                                 (R/ ) */
   t_int8u  clockDivider;             /*!<         0x1F: Clock Divider                            (R/W) */
} t_basiCan;


/*------------------------ PELI-CAN -----------------------*/

typedef struct
   {
   t_int8u  frameInfo;              /*!< Offset: 0x10: Frame Info Register:   RX=R/O, TX=W/O    (R/W) */
   t_int8u  ID_1;                   /*!<         0x11: Transmit ID 1:         RX=R/O, TX=W/O    (R/W) */
   t_int8u  ID_2;                   /*!<         0x12: Transmit ID 2:         RX=R/O, TX=W/O    (R/W) */
   t_int8u  data[C_CAN_BUF_SIZE];     /*!<   0x13..0x1A: Data:                  RX=R/O, TX=W/O    (R/W) */
   t_int8u  nextFrameInfo;          /*!<         0x1B: Next Frame Info:       RECEIVE-PATH ONLY (R/ ) */
   t_int8u  nextId1;                /*!<         0x1C: Next Frame ID1:        RECEIVE-PATH ONLY (R/ ) */
   } t_peliCanSff;

typedef struct
   {
   t_int8u  frameInfo;              /*!< Offset: 0x10: Frame Info Register:   RX=R/O, TX=W/O    (R/W) */
   t_int8u  ID_1;                   /*!<         0x11: Transmit ID 1:         RX=R/O, TX=W/O    (R/W) */
   t_int8u  ID_2;                   /*!<         0x12: Transmit ID 2:         RX=R/O, TX=W/O    (R/W) */
   t_int8u  ID_3;                   /*!<         0x13: Transmit ID 3:         RX=R/O, TX=W/O    (R/W) */
   t_int8u  ID_4;                   /*!<         0x14: Transmit ID 4:         RX=R/O, TX=W/O    (R/W) */
   t_int8u  data[C_CAN_BUF_SIZE];     /*!<   0x15..0x1C: Data:                  RX=R/O, TX=W/O    (R/W) */
   } t_peliCanEff;

typedef struct
   {
   t_int8u  acceptCode_0;           /*!< Offset: 0x10: Acceptance Code 0 Register   (R/W) */
   t_int8u  acceptCode_1;           /*!<         0x11: Acceptance Code 1            (R/W) */
   t_int8u  acceptCode_2;           /*!<         0x12: Acceptance Code 2            (R/W) */
   t_int8u  acceptCode_3;           /*!<         0x13: Acceptance Code 3            (R/W) */
   t_int8u  acceptMask_0;           /*!<         0x14: Acceptance Mask 0            (R/W) */
   t_int8u  acceptMask_1;           /*!<         0x15: Acceptance Mask 1            (R/W) */
   t_int8u  acceptMask_2;           /*!<         0x16: Acceptance Mask 2            (R/W) */
   t_int8u  acceptMask_3;           /*!<         0x17: Acceptance Mask 3            (R/W) */
   t_int8u  reserved_0;             /*!<         0x18: reserved                     (R/ ) */
   t_int8u  reserved_1;             /*!<         0x19: reserved                     (R/ ) */
   t_int8u  reserved_2;             /*!<         0x1A: reserved                     (R/ ) */
   t_int8u  reserved_3;             /*!<         0x1B: reserved                     (R/ ) */
   t_int8u  reserved_4;             /*!<         0x1C: reserved                     (R/ ) */
   } t_peliCanAccept;

typedef struct
   {
    t_int8u mode;                             /*!< Offset: 0x00: Mode Register                            (R/W) */
    t_int8u command;                          /*!<         0x01: Command                                  ( /W) */
    t_int8u status;                           /*!<         0x02: Status                                   (R/ ) */
    t_int8u interrupt;                        /*!<         0x03: Interrupt (reset on read, except bit0)   (R/ ) */
    t_int8u interruptEnable;                  /*!<         0x04: Interrupt Enable                         (R/W) */
    t_int8u reserved_0;                       /*!<         0x05: reserved                                 (R/ ) */
    t_int8u busTiming_0;                      /*!<         0x06: Bus Timing 0 (see "** note" below)       (R/W) */
    t_int8u busTiming_1;                      /*!<         0x07: Bus Timing 1 ("** note")                 (R/W) */
    t_int8u reserved_1;                       /*!<         0x08: reserved                                 (R/ ) */
    t_int8u reserved_2;                       /*!<         0x09: reserved                                 (R/ ) */
    t_int8u reserved_3;                       /*!<         0x0A: reserved                                 (R/ ) */
    t_int8u arbitrationLostCapture;           /*!<         0x0B: Arbitration Lost Capture                 (R/ ) */
    t_int8u errorCodeCapture;                 /*!<         0x0C: Error Code Capture                       (R/ ) */
    t_int8u errorWarningLimit;                /*!<         0x0D: Error Warning Limit ("** note")          (R/W) */
    t_int8u receiveErrorCounter;              /*!<         0x0E: Receive Error Counter ("** note")        (R/W) */
    t_int8u transmitErrorCounter;             /*!<         0x0F: Transmit Error Counter ("** note")       (R/W) */

   union
      {
      t_peliCanSff      SFF_Frame;             /*!<   0x10..0x1C: SFF Frame:            OPERATE MODE ONLY  */
      t_peliCanEff      EFF_Frame;             /*!<   0x10..0x1C: EFF Frame:            OPERATE MODE ONLY  */
      t_peliCanAccept   AcceptCodeMask;        /*!<   0x10..0x1C: Acceptance Code/Mask: RESET MODE ONLY    */
      };

   t_int8u RXMessageCounter;                   /*!<         0x1D: Receive Message Counter                  (R/ ) */
   t_int8u reserved_4;                         /*!<         0x1E: reserved                                 (R/ ) */
   t_int8u ClockDivider;                       /*!<         0x1F: Clock Divider                            (R/W) */
   } t_peliCan;

// ** note: writeable in RESET MODE only

/*------------------------  BASIC-CAN vs PELI-CAN Determination ------------------------ */

// used to set/determine (a) "BasiCAN vs PeliCAN" and (b) "SFF vs EFF" (EFF available in PeliCAN only)

typedef struct
   {
   t_int8u reset;                  /*!<         0x00: SET bit0 to reset                        (R/W) */
   t_int8u reserved_0[15];         /*!<   0x01..0x0F: reserved                                 (R/ ) */
   t_int8u FrameInfo;              /*!<         0x10: Frame Info Register (check bit7 for EFF) (R/W) */
   t_int8u reserved_1[14];         /*!<   0x11..0x1E: reserved                                 (R/ ) */
   t_int8u canMode;                /*!<         0x1F: Clock Divider (check bit7 for PeliCAN)   (R/W) */
   } t_genericCanAccess;

/*------------------------  BASIC-CAN / PELI-CAN ------------------------ */
typedef struct
{
 //union
		//{
		t_basiCan can;
		//t_peliCan can;
		//t_genericCanAccess GenericCAN_Access;
		//};
} t_canRegisters;



#endif


/** @}*/

....... And the result whas exactly the same !!!

Do you see any clear error that could generate this strange behaviour ?

According to tou, what could be the origin of the problem ?

I thank you for your help by advance.

Best regards.

Rémi G

Parents
  • A CAN node cannot live on its own.  At the very least, it expects to read its own signal back on CAN_RX, and at the corresponding point in the frame it requires an ACKnowledge signal from some other node to believe that it's doing everything correctly.  For your situation, that means at the very least you have to enable enough of your transceiver that it echoes back to the RX line.  Then you need some other node for your node to talk to.

Reply
  • A CAN node cannot live on its own.  At the very least, it expects to read its own signal back on CAN_RX, and at the corresponding point in the frame it requires an ACKnowledge signal from some other node to believe that it's doing everything correctly.  For your situation, that means at the very least you have to enable enough of your transceiver that it echoes back to the RX line.  Then you need some other node for your node to talk to.

Children