Forum: Mikrocontroller und Digitale Elektronik S32K144 nicht jede CAN Nachricht wird versendet


von Chandler B. (chandler)


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.

von Alexander (alecxs)


Lesenswert?


: Bearbeitet durch User
von Jens G. (jensig)


Lesenswert?

Chandler B. schrieb:
> Nach dem Aufstarten lese ich mir ein Paar Daten aus und möchte diese
> über CAN1 verschicken.

Vielleicht klemmt es ja schon an diesem Auslesen der Daten ...

von Luca E. (derlucae98)


Lesenswert?

Chandler B. schrieb:
> Nur es werden nicht alle Nachrichten gesendet.

Immer nur die erste?

Du schreibst drei mal hintereinander in den selben message buffer. Der 
MB ist solange blockiert, bis die Nachricht rausgeht.
Wenn am Bus nur ein Logic Analyzer hängt, blockiert der für immer, weil 
die Nachricht nicht mit einem ACK auf dem Bus bestätigt wird.

von Luca E. (derlucae98)



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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.