S32K144 nicht jede CAN Nachricht wird versendet

#7978560
Lesenswert?

Hallo, ich habe ein S32K144EVB-Q100. Hier habe ich noch einmal Probleme mit dem CAN1. Prinzipiell funktioniert es. Nur es werden nicht alle Nachrichten gesendet. Nach dem Aufstarten lese ich mir ein Paar Daten aus und möchte diese über CAN1 verschicken.

1
uint8_t canData1_au8[8] = {0};
2
uint8_t canData2_au8[8] = {0};
3
uint8_t canData3_au8[8] = {0};
4
... ... ...
5
... ... ...
6
FlexCAN1SendCanData(0x122, canData1_au8, 8);
7
FlexCAN1SendCanData(0x123, canData2_au8, 8);
8
FlexCAN1SendCanData(0x124, canData3_au8, 8);
1
void FLEXCAN1_init(void)
2
{
3
#define MSG_BUF_SIZE  4     /* Msg Buffer Size. (CAN 2.0AB: 2 hdr +  2 data= 4 words) */
4
  uint32_t   i=0;
5

6
  PCC->PCCn[PCC_FlexCAN1_INDEX] |= PCC_PCCn_CGC_MASK; /* CGC=1: enable clock to FlexCAN1 */
7

8
  CAN1->MCR |= CAN_MCR_MDIS_MASK;         /* MDIS=1: Disable module before selecting clock  */
9
  CAN1->CTRL1 &= ~CAN_CTRL1_CLKSRC_MASK;  /* CLKSRC=0: Clock Source = SOSCDIV2              */
10
  CAN1->MCR &= ~CAN_MCR_MDIS_MASK;        /* MDIS=0; Enable module config. (Sets FRZ, HALT) */
11

12
  while (!((CAN1->MCR & CAN_MCR_FRZACK_MASK) >> CAN_MCR_FRZACK_SHIFT))  {}
13
  CAN1->CTRL1 = 0
14
      |CAN_CTRL1_PSEG2(3)       /* Configure for 500 KHz bit time */
15
          |CAN_CTRL1_PSEG1(3)       /* Time quanta freq = 16 time quanta x 500 KHz bit time= 8MHz   */
16
          |CAN_CTRL1_PROPSEG(6)     /* PRESDIV+1 = Fclksrc/Ftq=8 MHz/8 MHz*/
17
          |CAN_CTRL1_RJW(3)         /*    so PRESDIV = 0    */
18
          |CAN_CTRL1_SMP(1);        /* PSEG2 = Phase_Seg2 - 1 = 4 - 1 = 3 */
19
                                            /* PSEG1 = PSEG2 = 3 */
20
                                    /* PROPSEG= Prop_Seg - 1 = 7 - 1 = 6 */
21
                                    /* RJW: since Phase_Seg2 >=4, RJW+1=4 so RJW=3.                 */
22
                                    /* SMP = 1: use 3 bits per CAN sample */
23
                                    /* CLKSRC=0 (unchanged): Fcanclk= Fosc= 8 MHz                   */
24

25
  for(i=0; i<64; i++ )
26
  {                     /* CAN1: clear 16 msg bufs x 4 words/msg buf = 64 words */
27
    CAN1->RAMn[i] = 0;  /* Clear msg buf word */
28
  }
29
  for(i=0; i<16; i++ )
30
  {                                 /* In FRZ mode, init CAN1 16 msg buf filters */
31
    //CAN1->RXIMR[i] = 0xFFFFFFFF;      /* Check all ID bits for incoming messages */
32
    CAN1->RXIMR[i] = 0x00000000;    /* Check No ID bits for incoming messages */
33
  }
34
  //CAN1->RXMGMASK = 0x1FFFFFFF;                /* Global acceptance mask: check all ID bits    */
35
  CAN1->RXMGMASK = 0x00000000;                  /* Global acceptance mask: check no ID bits     */
36

37
  CAN1->RAMn[ 4*MSG_BUF_SIZE + 0] = 0x04000000; /* Msg Buf 4, word 0: Enable for reception  */
38
                                                /* EDL,BRS,ESI=0: */
39
                                                /* CODE=4: */
40
                                                /* IDE=0 */
41
                                                /* SRR, RTR, TIMESTAMP=0*/
42

43
   CAN1->RAMn[ 4*MSG_BUF_SIZE + 1] = 0x14440000;
44
                                                /* Msg Buf 4, word 1*/
45
                                                /* PRIO=0: CANFD not used */
46

47
  CAN1->MCR = 0x0000001F;                       /* Negate FlexCAN 1 halt state for 32 MBs */
48

49
  while ((CAN1->MCR && CAN_MCR_FRZACK_MASK) >> CAN_MCR_FRZACK_SHIFT)  {}
50
  /* Good practice: wait for FRZACK to clear (not in freeze mode) */
51

52
  while ((CAN1->MCR && CAN_MCR_NOTRDY_MASK) >> CAN_MCR_NOTRDY_SHIFT)  {}
53
  /* Good practice: wait for NOTRDY to clear (module ready) */
54
}
55

56

57
void FlexCAN1SendCanData(uint16_t id_u8, uint8_t* data_pu8, uint8_t lenght_u8)
58
{
59
    uint32_t word0 = 0;
60
    uint32_t word1 = 0;
61
    uint32_t word2 = 0;
62
    uint32_t word3 = 0;
63

64
    word0 = 0x0C400000 | (8 << CAN_WMBn_CS_DLC_SHIFT);  /* MB0 word 0 */
65
                                                        /* bit 31: EDL=0*/
66
                                                        /* bit 30: BRS=0*/
67
                                                        /* bit 29: ESI=0*/
68
                                                        /* bit 27-24: CODE=0xC*/
69
                                                        /* bit 22: SRR=1 */
70
                                                        /* bit 21: IDE=0 */
71
                                                        /* bit 20: RTR=0*/
72
                                                        /* bit 19-16: DLC=8*/
73
                                                        /* bit 15-0: TIMESTAMP */
74
    word1 = ((uint32_t)id_u8 << 18); /* MB0 word 1 */
75
              /* Tx msg with STD ID  */
76
                                        /* bit 31-29: PRIO = 0 */
77
                                        /* bit 28-18: ID (standard) */
78
                                        /* bit 17-0: ID (extended) */
79

80
    word2 = ((uint32_t)data_pu8[0] << 24) 
81
              | ((uint32_t)data_pu8[1] << 16)
82
              | ((uint32_t)data_pu8[2] << 8)
83
              | ((uint32_t)data_pu8[3] << 0); /* MB0 word 2 */
84
    word3 = ((uint32_t)data_pu8[4] << 24)
85
              | ((uint32_t)data_pu8[5] << 16)
86
              | ((uint32_t)data_pu8[6] << 8)
87
              | ((uint32_t)data_pu8[7] << 0); /* MB0 word 3 */
88

89

90
    CAN1->IFLAG1 = 0x00000001;  /* Clear CAN 1 MB 0 flag without clearing others*/
91
    CAN1->RAMn[ 0*MSG_BUF_SIZE + 1] = word1;
92
    CAN1->RAMn[ 0*MSG_BUF_SIZE + 2] = word2;
93
    CAN1->RAMn[ 0*MSG_BUF_SIZE + 3] = word3;
94
    CAN1->RAMn[ 0*MSG_BUF_SIZE + 0] = word0; // CODE is written here to activate transmission
95
}

Die Nachrichten gehen nicht aus dem S32K144 heraus. Ich sehe die Nachrichten auch nicht auf der CAN1_TX-Leitung. Dort habe ich einen Logikanalyzer dran hängen.

#7979690
Lesenswert?

Ergänzend zu meinem letzten post: Schau dir doch mal das CODE Feld im Message buffer an. Das sollte in deinem Fall immer 0b1100 bleiben.

Bevor du die nächste Nachricht sendest, solltest du warten bis CODE = 0b1000 (Inactive) wird bzw. den entsprechenden Interrupt nutzen. Alternativ kannst du auch über deine MBs iterieren und den nächsten freien benutzen. Dann kümmert sich der CAN-Controller darum, dass alle Nachrichten zeitnah rausgehen. Das alles funktioniert aber wie gesagt nur, wenn mindestens ein weiterer Teilnehmer am Bus hängt, der die Nachrichten bestätigt.

Der ganze Prozess ist im Reference Manual unter 55.5.1 Transmit process beschrieben.

Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren