Search code examples
cembeddedcan-busstm32f4

CAN with STM32F4


Right now I am working with an STMF429 nucleo-144 board and I am trying get the CAN to work. Here is my Code:

int intCAN();
int intFilter();
int pins();

int main(void)
{

    //int CAN
    pins();
    intFilter();
    intCAN();
    CAN1->sTxMailBox[0].TDLR = 0;
    CAN1->sTxMailBox[0].TDHR = 0;

    CAN1->sTxMailBox[0].TDLR |= 0x8;            //DATA0 = 1000


    CAN1->sTxMailBox[0].TIR |= CAN_TI0R_TXRQ;   //send mailbox
}

int pins()
{
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
    //RX
    GPIOD->MODER &= GPIO_MODER_MODER0_1;
    GPIOD->OTYPER &= ~(GPIO_OTYPER_OT0);
    GPIOD->PUPDR &= ~(GPIO_PUPDR_PUPDR0);
    GPIOD->OSPEEDR |= GPIO_OSPEEDR_OSPEED0_0|GPIO_OSPEEDR_OSPEED0_1;
    //TX
    GPIOD->MODER |= GPIO_MODER_MODER1_1;
    GPIOD->OTYPER &= ~(GPIO_OTYPER_OT1);
    GPIOD->PUPDR &= ~(GPIO_PUPDR_PUPDR1);
    GPIOD->OSPEEDR |= GPIO_OSPEEDR_OSPEED1_0|GPIO_OSPEEDR_OSPEED1_1;
    return 0;
}

int intCAN()
{
    RCC->APB1ENR |= RCC_APB1ENR_CAN1EN;
    CAN1->MCR &= ~(CAN_MCR_SLEEP);
    CAN1->MCR |= CAN_MCR_INRQ;      //Initilization Request
    CAN1->BTR |= CAN_BTR_LBKM;      //Loop Back Mode
    CAN1->BTR |= 0x7;           //BRP = 7
    CAN1->BTR |= CAN_BTR_TS2_0|CAN_BTR_TS2_1|CAN_BTR_TS2_2;     //Seg 2 = 7
    CAN1->BTR |= CAN_BTR_TS1_0|CAN_BTR_TS1_1|CAN_BTR_TS1_2|CAN_BTR_TS1_3;   //Seg 1 = 16
    CAN1->BTR |= CAN_BTR_SJW_0;     //Small Jump Width = 1

    CAN1->MCR &= ~(CAN_MCR_INRQ);               //exit initilization mode

    //Testing
    CAN1->sTxMailBox[0].TIR &= ~CAN_TI0R_RTR;
    CAN1->sTxMailBox[0].TIR &= ~CAN_TI0R_IDE;       //Standard Identifier
    CAN1->sTxMailBox[0].TIR &= ~CAN_TI0R_STID;
    CAN1->sTxMailBox[0].TIR |= (0x1 << CAN_TI0R_STID_Pos);              //Message ID = 1


    //Message
    CAN1->sTxMailBox[0].TDTR &= ~CAN_TDT0R_DLC;
    CAN1->sTxMailBox[0].TDTR |= (0x1 << CAN_TDT0R_DLC_Pos);         //Data Length = 1 Byte
    return 0;
}

int intFilter()
{
    RCC->APB1ENR |= RCC_APB1ENR_CAN1EN;
    CAN1->FA1R &= ~(CAN_FA1R_FACT0);
    CAN1->FMR |= CAN_FMR_FINIT;     //Initilization Mode Filter
    CAN1->FM1R |= CAN_FM1R_FBM0;    //Filter Bank 0 2 32bit register Identifier List Mode
    CAN1->FS1R |= CAN_FS1R_FSC0;
    CAN1->FFA1R &= ~(CAN_FFA1R_FFA0);
    CAN1->sFilterRegister[0].FR1 |= 0x0;
    CAN1->sFilterRegister[0].FR1 |= CAN_F0R1_FB0;   //ID Filter = 1
    CAN1->FMR &= ~(CAN_FMR_FINIT);  //Exit Initilization Mode Filter
    CAN1->FA1R |= CAN_FA1R_FACT0;
    return 0;

The TX Pin is the PD0 Pin and the RX Pin is the PD1 Pin When I run this program all I get is a constant dominant signal which is not what I´m hoping for. I am testing just the TX Pin with an logic analyser. I´m pretty confident that it is mostly true but that I am missing something (obvious). I want to just use the registers (CMSIS) and no HAL. Does anyone have an idea what I can do?

Thanks in advance Jeyeffkay

I tried it in Loopback Mode and in different configurations but nothing worked. I´m new to this.

Edit1: At first I just want to have the desired output which should be a whole CAN Message which I can view in the Logic Analyser.


Solution

  • I found out why it didn´t worked. I set the GPIO Pins to Alternate function but I had to specify which alternate function to use so I had to add the following:

        RCC->AHB1ENR |= RCC_AHB1ENR_GPIODEN;
        (void)RCC->AHB1ENR;
        //RX
        GPIOD->MODER |= GPIO_MODER_MODER0_1;
        GPIOD->AFR[0] |= GPIO_AFRL_AFRL0_0|GPIO_AFRL_AFRL0_3;   //this was missing
        GPIOD->OTYPER &= ~(GPIO_OTYPER_OT0);
        GPIOD->PUPDR &= ~(GPIO_PUPDR_PUPDR0);
        GPIOD->OSPEEDR |= GPIO_OSPEEDR_OSPEED0_0|GPIO_OSPEEDR_OSPEED0_1;
        //TX
        GPIOD->MODER |= GPIO_MODER_MODER1_1;
        GPIOD->AFR[0] |= GPIO_AFRL_AFRL1_0|GPIO_AFRL_AFRL1_3;    //and this
        GPIOD->OTYPER &= ~(GPIO_OTYPER_OT1);
        GPIOD->PUPDR &= ~(GPIO_PUPDR_PUPDR1);
        GPIOD->OSPEEDR |= GPIO_OSPEEDR_OSPEED1_0|GPIO_OSPEEDR_OSPEED1_1;
        return 0;
    

    Now CAN works, right now I am not getting the Output I hoped for but I´m getting there.