2015-07-20 01:02 AM
Hi Guys,
I'm struggling to activate the can bus in the CAN2 module in the discovery eval board.Using CubeMx, Generated all the initialization code.Set baud-rate to 50KHz, and to loop-back mode.The output waveform looks very strange, and does not change as a result of the transmitted data or ID. The returned status is 3, which is timeout.Attached my test code, and the scope waveform from the CAN2-tx on PB6.main.c includes all the default initialization, created by cube.Here is the transmission code:HAL_StatusTypeDef status;
static CanTxMsgTypeDef txMsg;
static CanRxMsgTypeDef rxMsg;
static CAN_FilterConfTypeDef sFilterConfig;
hcan2.pTxMsg = &txMsg;
hcan2.pRxMsg = &rxMsg;
txMsg.StdId = 0x7ff;
txMsg.ExtId = 0;
txMsg.IDE = CAN_ID_STD;
txMsg.RTR = CAN_RTR_DATA;
txMsg.DLC = 2;
txMsg.Data[0] = 0x12;
txMsg.Data[1] = 0x34;
status = HAL_CAN_Transmit(&hcan2, 1000);
PRINT(''%d\n'', status);
Thanks, Isak. #can #stm32f407 #discovery
2015-07-20 11:12 AM
Does the scope understand CAN_TX vs CAN_H/L ?
In most real applications you need a transceiver, and a responding node.Can't help you with Cube/HAL, but 50Hz and 1TQ all seems a bit odd.2015-07-20 04:15 PM
I can't help with the HAL stuff but here is a modified version of the Keil setup example
which runs at 50KHz on a F429 (running at 180MHz, so you may need to change the BTR values if your running at 168MHz) but the maths is quite straightforward and even easier if you put the formula into Excel. Also, in loopback mode would you see any data on the output?/*----------------------------------------------------------------------------
setup CAN interface
*----------------------------------------------------------------------------*/
void CAN_setup (uint32_t ctrl) {
CAN_TypeDef *pCAN = (ctrl == 1) ? CAN1 : CAN2;
uint32_t brp;
if (ctrl == 1) {
/* Enable clock for CAN1 and GPIOB */
RCC->APB1ENR |= (1 <<
25
);
RCC->AHB1ENR |= (1 <<
1
);
/* CAN1, use PB8, PB9 */
GPIOB->MODER &= ~(( 3 << ( 8*2)) | ( 3 << ( 9*2)));
GPIOB->MODER |= (( 2 << ( 8*2)) | ( 2 << ( 9*2)));
GPIOB->OTYPER &= ~(( 1 <<
8
) | ( 1 << 9 ));
GPIOB->OSPEEDR &= ~(( 3 << ( 8*2)) | ( 3 << ( 9*2)));
GPIOB->PUPDR &= ~(( 3 << ( 8*2)) | ( 3 << ( 9*2)));
GPIOB->AFR[1] &= ~((15 << ( 0*4)) | (15 << ( 1*4)));
GPIOB->AFR[1] |= (( 9 << ( 0*4)) | ( 9 << ( 1*4)));
NVIC_EnableIRQ (CAN1_TX_IRQn); /* Enable CAN1 interrupts */
NVIC_EnableIRQ (CAN1_RX0_IRQn);
NVIC_EnableIRQ (CAN1_SCE_IRQn); // CAN1 Error Detection
// CAN1 Automatic Retransmission used
pCAN->MCR = (CAN_MCR_INRQ); /* initialisation request */
/* AUTOMATIC RETRANSMISSION */
/* only FIFO 0, tx mailbox 0 used! */
} else {
/* Enable clock for CAN2 and GPIOB */
RCC->APB1ENR |= (1 <<
25
) | (1 << 26);
RCC->AHB1ENR |= (1 <<
1
);
/* CAN2, use PB12, PB13 */
GPIOB->MODER &= ~(( 3 << ( 12*2)) | ( 3 << ( 13*2)));
GPIOB->MODER |= (( 2 << ( 12*2)) | ( 2 << ( 13*2)));
GPIOB->OTYPER &= ~(( 1 <<
12
) | ( 1 << 13 ));
GPIOB->OSPEEDR &= ~(( 3 << ( 12*2)) | ( 3 << ( 13*2)));
GPIOB->PUPDR &= ~(( 3 << ( 12*2)) | ( 3 << ( 13*2)));
GPIOB->AFR[1] &= ~((15 << ( 4*4)) | (15 << ( 5*4)));
GPIOB->AFR[1] |= (( 9 << ( 4*4)) | ( 9 << ( 5*4)));
NVIC_EnableIRQ (CAN2_TX_IRQn); /* Enable CAN2 interrupts */
// NVIC_EnableIRQ (CAN2_RX0_IRQn);
NVIC_EnableIRQ (CAN2_SCE_IRQn); // CAN2 Error Detection
// CAN2 Detects TX Failure and handles it in code
pCAN->MCR = (CAN_MCR_INRQ | /* initialisation request */
CAN_MCR_NART ); /* no automatic retransmission */ /* only FIFO 0, tx mailbox 0 used! */
}
//=================================================================
while (!(pCAN->MSR & CAN_MCR_INRQ));
pCAN->IER = (CAN_IER_FMPIE0 | /* enable FIFO 0 msg pending IRQ */
CAN_IER_TMEIE | /* enable Transmit mbx empty IRQ */
CAN_IER_LECIE ); // Enable Last Error Code IRQ
pCAN->BTR = 0x0338003F; // SWJ=3, TS2=0x3, TS1=0x8, BRP=0x3F
}