Forum: Mikrocontroller und Digitale Elektronik S32K144 FlexCAN1 probleme


von Chandler B. (chandler)


Angehängte Dateien:

Lesenswert?

Hallo,
ich habe einen S32K144EVB-Q100 -und möchte auf diesen FlexCAN1 
verwenden.
Ich habe dazu das Beispiel von FlexCAN0 genommen und überall CAN0 in 
CAN1 umbenannt.
Da der message Buffer für FlexCAN1 nicht so groß ist, habe ich hier 
weniger buffer mit 0 initialisirt.

Ich habe jetzt zwei Probleme.
1. Wenn ich zyklisch eine CAN-Nachricht schicken möchte, passiert 
nichts. Ich sehe noch nicht einmal etwas auf der CAN1_TX Leitung (dort 
hängt ein Logikanalyzer dran)

2. Laut dem Referenc Manual ist das Register PCC FlexCAN1 bei einem 
Offset von 94h (siehe FlexCAN1_Register.png)

Wenn ich in S32K144.h nachschaue, ist dort ein define
1
#define PCC_FlexCAN1_INDEX        37
Dies wird in der Initialisierung verwendet
1
  PCC->PCCn[PCC_FlexCAN1_INDEX] |= PCC_PCCn_CGC_MASK; /* CGC=1: enable clock to FlexCAN1 */
Wie passt das überein?
1
int main(void)
2
{
3
      /*!
4
       * Initialization:
5
       * =======================
6
       */
7
    WDOG_disable();        /* Disable WDOG */
8
    SOSC_init_8MHz();        /* Initialize system oscillator for 8 MHz xtal */
9
    SPLL_init_160MHz();      /* Initialize SPLL to 160 MHz with 8 MHz SOSC */
10
    NormalRUNmode_80MHz();   /* Init clocks: 80 MHz sysclk & core, 40 MHz bus, 20 MHz flash */
11
    FLEXCAN1_init();
12
    PORT_init();             /* Configure ports */
13
    LPSPI1_init_master();    /* Initialize LPSPI 1 as master */
14
    LPIT0_init();           /* Initialize PIT0 for 500 ms timeout */
15
    SBC_Init();
16
    lightInit_v();
17
18
    for(;;)
19
    {
20
        while (0 == (LPIT0->MSR & LPIT_MSR_TIF0_MASK)) {} /* Wait for LPIT0 CH0 Flag */
21
        toggleAnalyzePin_v();
22
        toggleLightPin_v(color);
23
        LPIT0->MSR |= LPIT_MSR_TIF0_MASK;               /* Clear Flag */
24
        FLEXCAN1_transmit_msg();
25
    }
26
}

PORT_init():
1
void PORT_init (void)
2
{
3
    /*!
4
     * Pins definitions
5
     * ===================================================
6
     *
7
     * Pin number        | Function
8
     * ----------------- |------------------
9
     * SPI
10
     * PTB14             | LPSPI1_SCK
11
     * PTB15             | LPSPI1_SIN
12
     * PTB16             | LPSPI1_SOUT
13
     * PTA6              | LPSPI1_PCS1
14
     *
15
     * GPIO
16
     * PTD16             | GPIO output [LED_GREEN]
17
     * PTD15             | GPIO output [LED_RED]
18
     *
19
     * CAN
20
     * PTA12             | CAN1_RX
21
     * PTA13             | CAN1_TX
22
     *
23
     */
24
    // SPI
25
    PCC->PCCn[PCC_PORTB_INDEX ]|=PCC_PCCn_CGC_MASK; /* Enable clock for PORTB */
26
    PORTB->PCR[14]|=PORT_PCR_MUX(3); /* Port B14: MUX = ALT3, LPSPI1_SCK */
27
    PORTB->PCR[15]|=PORT_PCR_MUX(3); /* Port B15: MUX = ALT3, LPSPI1_SIN */
28
    PORTB->PCR[16]|=PORT_PCR_MUX(3); /* Port B16: MUX = ALT3, LPSPI1_SOUT */
29
    //PORTB->PCR[17]|=PORT_PCR_MUX(3); /* Port B17: MUX = ALT3, LPSPI1_PCS3 */
30
    PCC->PCCn[PCC_PORTA_INDEX ]|=PCC_PCCn_CGC_MASK; /* Enable clock for PORTA */
31
    PORTA->PCR[6]|=PORT_PCR_MUX(3); /* Port A06: MUX = ALT3, LPSPI1_PCS3 */
32
33
    // GPIO
34
    PCC->PCCn[PCC_PORTD_INDEX ]|=PCC_PCCn_CGC_MASK; /* Enable clock for PORTD */
35
    PORTD->PCR[16]|=PORT_PCR_MUX(1); /* Port D16: MUX = ALT1, GPIO */
36
    PTD->PDDR |= 1<<16;               /* Port D16: Data Direction= output */
37
    PORTD->PCR[15]|=PORT_PCR_MUX(1); /* Port D16: MUX = ALT1, GPIO */
38
    PTD->PDDR |= 1<<15;               /* Port D16: Data Direction= output */
39
    PORTA->PCR[11]|=PORT_PCR_MUX(1); /* Port A11: MUX = ALT1, GPIO */
40
    PTA->PDDR |= 1<<11;               /* Port A11: Data Direction= output */
41
    PTA->PSOR |= 1<<11; // low
42
43
    // CAN
44
    PORTA->PCR[12] |= PORT_PCR_MUX(5);  /* Port A12: MUX = ALT5, CAN0_RX */
45
    PORTA->PCR[13] |= PORT_PCR_MUX(5); /* Port A13: MUX = ALT5, CAN0_TX */
46
47
}

von Manuel H. (Firma: Universität Tartu) (xenos1984)


Lesenswert?

Chandler B. schrieb:
> Wenn ich in S32K144.h nachschaue, ist dort ein define#define
> PCC_FlexCAN1_INDEX        37
> Dies wird in der Initialisierung verwendet
> PCC->PCCn[PCC_FlexCAN1_INDEX] |= PCC_PCCn_CGC_MASK; /* CGC=1: enable
> clock to FlexCAN1 */
> Wie passt das überein?

Ich denke, die Register sind 4 byte breit. 37 \* 4 = 148 = 94h.

von Luca E. (derlucae98)


Lesenswert?

Chandler B. schrieb:
> // CAN
>     PORTA->PCR[12] |= PORT_PCR_MUX(5);  /* Port A12: MUX = ALT5, CAN0_RX
> */
>     PORTA->PCR[13] |= PORT_PCR_MUX(5); /* Port A13: MUX = ALT5, CAN0_TX
> */

Der Port-Mux für CAN1 ist 3, nicht 5.

von Chandler B. (chandler)


Lesenswert?

Luca E. schrieb:
> Der Port-Mux für CAN1 ist 3, nicht 5.

Ja, das wars :)
Danke für den Hinweis.

Senden funktioniert jetzt schonmal. Empfangen muss ich noch schauen. Ich 
schicke mir von CANoe die NAchricht direkt. Ich sehe die Nachricht auch 
auf der CAN_RX line, aber im Code kommt die irgendwie noch nicht an. Da 
muss ich nochmal weiterschauen.

von Chandler B. (chandler)


Lesenswert?

Ich habe doch noch Probleme (Verständnisprobleme) zum Empfangen von den 
CAN-Nachrichten.
1
void FlexCAN1SendCanData(uint16_t id_u8, uint8_t* data_pu8, uint8_t lenght_u8)
2
{
3
    uint32_t word0 = 0;
4
    uint32_t word1 = 0;
5
    uint32_t word2 = 0;
6
    uint32_t word3 = 0;
7
8
    word0 = 0x0C400000 | (8 << CAN_WMBn_CS_DLC_SHIFT);  /* MB0 word 0 */
9
                                    /* bit 31: EDL=0: */
10
                                    /* bit 30: BRS=0: */
11
                                    /* bit 29: ESI=0: */
12
                                    /* bit 27-24: CODE=0xC: Activate tx */
13
                                    /* bit 22: SRR=1 Tx frame */
14
                                    /* bit 21: IDE=0: Standard ID */
15
                                    /* bit 20: RTR = 0*/
16
                                    /* bit19-16:DLC=8 */
17
                                    /* bit 15-0: TIME STAMP = 0 */
18
    word1 = ((uint32_t)id_u8 << 18); /* MB0 word 1 */
19
                      /* Tx msg with STD ID 0x555 */
20
                      /* bit 31-29: PRIO = 0 */
21
                      /* bit 28-18: ID (standard) = 0x555 */
22
                      /* bit 17-0: ID (extended) = 0x00 */
23
24
    word2 = data_pu8[0] | ((uint32_t)data_pu8[1] << 8) | ((uint32_t)data_pu8[2] << 16) | ((uint32_t)data_pu8[3] << 24); /* MB0 word 2 */
25
    word3 = data_pu8[4] | ((uint32_t)data_pu8[5] << 8) | ((uint32_t)data_pu8[6] << 16) | ((uint32_t)data_pu8[7] << 24); /* MB0 word 3 */
26
27
28
    CAN1->IFLAG1 = 0x00000001;  /* Clear CAN 1 MB 0 flag without clearing others*/
29
    CAN1->RAMn[ 0*MSG_BUF_SIZE + 1] = word1;
30
    CAN1->RAMn[ 0*MSG_BUF_SIZE + 2] = word2;
31
    CAN1->RAMn[ 0*MSG_BUF_SIZE + 3] = word3;
32
    CAN1->RAMn[ 0*MSG_BUF_SIZE + 0] = word0;
33
}
34
35
void FLEXCAN1_receive_msg(void)
36
{
37
  uint8_t j;
38
  uint32_t dummy;
39
40
  RxCODE   = (CAN1->RAMn[ 4*MSG_BUF_SIZE + 0] & 0x07000000) >> 24;  /* Read CODE field */
41
  RxID     = (CAN1->RAMn[ 4*MSG_BUF_SIZE + 1] & CAN_WMBn_ID_ID_MASK)  >> CAN_WMBn_ID_ID_SHIFT;  /* Read ID          */
42
  RxLENGTH = (CAN1->RAMn[ 4*MSG_BUF_SIZE + 0] & CAN_WMBn_CS_DLC_MASK) >> CAN_WMBn_CS_DLC_SHIFT; /* Read Message Length */
43
44
  for (j=0; j<2; j++)
45
  {  /* Read two words of data (8 bytes) */
46
    RxDATA[j] = CAN1->RAMn[ 4*MSG_BUF_SIZE + 2 + j];
47
  }
48
  RxTIMESTAMP = (CAN1->RAMn[ 4*MSG_BUF_SIZE + 0] & 0x000FFFF);
49
  dummy = CAN1->TIMER;             /* Read TIMER to unlock message buffers */
50
  CAN1->IFLAG1 = 0x00000010;       /* Clear CAN 1 MB 4 flag without clearing others*/
51
}

in main.c
1
    for(;;)
2
    {
3
        while (0 == (LPIT0->MSR & LPIT_MSR_TIF0_MASK)) {} /* Wait for LPIT0 CH0 Flag */
4
        LPIT0->MSR |= LPIT_MSR_TIF0_MASK;               /* Clear Flag */
5
6
        FlexCAN1SendCanData(0x123, canData_au8, 8);
7
        if ((CAN1->IFLAG1 >> 4) & 1)
8
        //if (CAN_IFLAG1_BUF4TO1I(4))
9
        {
10
            FLEXCAN1_receive_msg();
11
        }
12
    }

Mein Problem ist, dass das CAN_IFLAG1_BUF4TO1I(4) bit immer gesetzt ist, 
obwohl ich von außen gar keine CAN-Nachrichten sende.
Die Daten die ich dann auslese, sind die Daten aus Mailbox0, also das 
was ich sende.
Wird beim senden von Mailbox 0 das bit für Mailbox 4 gesetzt?
Das Bit lösche ich ja eigentlich wieder in FLEXCAN1_receive_msg();
Wie kann ich verhindern, dass beim Senden von Mailbox 0 das Bit für 
Mailbox 4 gesetzt wird?

: Bearbeitet durch User
von Luca E. (derlucae98)


Lesenswert?

Chandler B. schrieb:
> Die Daten die ich dann auslese, sind die Daten aus Mailbox0, also das
> was ich sende.

Das ist wohl ganz normal beim FlexCAN-Modul. Der einzige mir bekannte 
Weg das zu verhindern, ist die eigenen IDs mit dem Empfangsfilter 
wegzufiltern, sodass sie dir die Message Buffer nicht zumüllen.

Chandler B. schrieb:
> Wie kann ich verhindern, dass beim Senden von Mailbox 0 das Bit für
> Mailbox 4 gesetzt wird?

Was spricht dagegen bei einer neuen Nachricht über alle Message Buffer 
zu iterieren und alle eingehenden Nachrichten zu verarbeiten? Mir war 
das zumindest immer egal, welcher Message Buffer zuerst gefüllt wurde.

Zur Inspiration: 
https://github.com/derlucae98/spr-bmu-firmware/blob/ee3239ad22018220fd7fe1fbe2be26231e18262b/driver/can.c#L147

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.