cancel
Showing results for 
Search instead for 
Did you mean: 

CAN message not sent.

Hosting
Associate III

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;

}

3 REPLIES 3

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 Up vote any posts that you find helpful, it shows what's working..
Hosting
Associate III

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

T J
Lead

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