Skip to main content
Hosting
Associate III
October 21, 2018
Question

CAN message not sent.

  • October 21, 2018
  • 3 replies
  • 752 views

Hi! CAN message not sent. Please see where I'm wrong?

int main (void){

SysClock();

CanInit();

CanFilter();

CAN_ConfigInterupt();

while(1)

{

TransmitMsg();

delay(100);

}

}

void CanInit (void){

//PA12 - CAN=TX

//PA11 - CAN-RX

RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;

RCC->APB2ENR |= RCC_APB2ENR_AFIOEN;

RCC->APB1ENR |= RCC_APB1ENR_CAN1EN;

GPIOA->CRH |= GPIO_CRH_CNF11_1; //Input with pull-up / pull-down

GPIOA->CRH &= ~GPIO_CRH_MODE11; //Input mode (reset state)

GPIOA->CRH |= GPIO_CRH_CNF12_1; //Alternate function output Push-pull

GPIOA->CRH |= GPIO_CRH_MODE12; //Output mode, max speed 50 MHz.

AFIO->MAPR &= ~AFIO_MAPR_CAN_REMAP;

CAN1->MCR |= CAN_MCR_INRQ;

while(!(CAN1->MSR & CAN_MSR_INAK));

  CAN1->MCR &= ~CAN_MCR_TTCM;  

  CAN1->MCR &= ~CAN_MCR_ABOM;   

  CAN1->MCR &= ~CAN_MCR_AWUM;   

  CAN1->MCR &= ~CAN_MCR_NART;   

  CAN1->MCR &= ~CAN_MCR_RFLM;   

  CAN1->MCR &= ~CAN_MCR_TXFP;   

  /******************** 500kbit/s ***************************/

  CAN1->BTR = 0;

  

  CAN1->BTR |= (3 << 0) BRP 3

     | (11 << 16) //TS1 = 11

 | (4 << 20) //TS2 = 4

 | (2 << 24) //SJW = 2

 | (1 << 30) //Loop Back Mode enabled

 | (1 << 31); //Silent Mode

  /************************************************************************/

  CAN1->MCR &= ~CAN_MCR_INRQ;

  while(CAN1->MSR & CAN_MSR_INAK);

}

void CanFilter(void)

{

CAN1->FMR |= CAN_FMR_FINIT;

CAN1->FMR |= CAN_FMR_CAN2SB;

CAN1->FM1R &= ~CAN_FM1R_FBM0;  

CAN1->FS1R = CAN_FS1R_FSC0;

CAN1->FFA1R = 0x00;

CAN1->sFilterRegister[0].FR1 = 0x0;

CAN1->sFilterRegister[0].FR2 = 0x0;

CAN1->FA1R = CAN_FA1R_FACT0;

CAN1->FMR &= ~CAN_FMR_FINIT;

}

void TransmitMsg(void)

{

uint8_t Data[8];

Data[0] = 1;

Data[1] = 2;

Data[2] = 3;

Data[3] = 4;

Data[4] = 5;

Data[5] = 6;

Data[6] = 7;

Data[7] = 8;

CAN1->sTxMailBox[0].TIR |= (0x222 << 21);

CAN1->sTxMailBox[0].TDTR &= 0xFFFFFFF0U;

CAN1->sTxMailBox[0].TDTR |= 8;

CAN1->sTxMailBox[0].TDLR |= (((uint32_t)Data[3] << (24U)) |

                ((uint32_t)Data[2] << (16U)) |

                ((uint32_t)Data[1] << (8U)) |

                ((uint32_t)Data[0] << (0U)));

CAN1->sTxMailBox[0].TDHR |= (((uint32_t)Data[7] << CAN_TDL0R_DATA3_Pos) |

                ((uint32_t)Data[6] << CAN_TDL0R_DATA2_Pos) |

                ((uint32_t)Data[5] << CAN_TDL0R_DATA1_Pos) |

                ((uint32_t)Data[4] << CAN_TDL0R_DATA0_Pos));

CAN1->sTxMailBox[0].TIR |= CAN_TI0R_TXRQ;

}

    This topic has been closed for replies.

    3 replies

    Tesla DeLorean
    Guru
    October 21, 2018

    This style of code is very difficult to follow, and doing multiple RMW is rather inefficient.

    Not sure I'd be ORing values into the mailbox like this.

    Perhaps before engaging everyone else to inspect register level code, try using the library code and examples, prove that works, or not, and then decompose that to register level if you have some perceived benefit from doing that.

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    Hosting
    HostingAuthor
    Associate III
    October 21, 2018

    Using the HAL library, works. But I want to understand this protocol more deeply.

    T J
    Senior III
    October 21, 2018

    try to enable ABOM...

    did you get the receiver running first ?

    much easier to work that way.

    I set a CanDo unit transmitting every second to work on the receiver...

    that sets all the clocks correctly, then you can do the Tx.

    I use this to transmit:

    if ((CAN1->TSR & CAN_TSR_TME0) == CAN_TSR_TME0) // (1) 
    {
     CAN1->sTxMailBox[0].TDTR = canTxMsgLength[canTxMsgOUT]; // (2) length
     CAN1->sTxMailBox[0].TDLR = canTxMsgBottomWord[canTxMsgOUT]; // (3) 4bytes
     CAN1->sTxMailBox[0].TDHR = canTxMsgTopWord[canTxMsgOUT]; // (3) 4bytes
     
     
     CAN1->sTxMailBox[0].TIR = ((uint32_t)canTxMsgID [canTxMsgOUT] << 21 | CAN_TI0R_TXRQ); 
    	// send it now if the line is idle