2014-01-31 02:25 PM
Hello, Iam working on my can project with discovery f429 kit. Now I have it conneced to MCP2551 transciever and to NI-CAN reader (as far as I know it should act as 2. node as it is sending acknowledgment)
Iam fine with loopback mode. I can read the data from NI-CAN and also I can receive them looped at my board. So it looks like can is working perfectly with baudrate and GPIO output. Problem is when I want to go normal mode. It does nothing. Iam initialising it as loopback and at the end of all peripheral init I switch it to normal mode. Thank you for help :)AN_InitTypeDef CAN_InitStructure;
void CAN_RCC_Configuration(void)
{
/* CAN1 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
/* CAN2 clock enable */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN2, ENABLE);
/* Init CAN GPIO clocks */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
}
void CAN_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructureCAN_RX;
GPIO_InitTypeDef GPIO_InitStructureCAN_TX;
/* GPIO CAN_RX Configuration */
GPIO_InitStructureCAN_RX.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructureCAN_RX.GPIO_Mode = GPIO_Mode_AF;
//GPIO_InitStructureCAN_RX.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructureCAN_RX.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOB, &GPIO_InitStructureCAN_RX);
/* GPIO CAN_TX Configuration */
GPIO_InitStructureCAN_TX.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructureCAN_TX.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructureCAN_TX.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructureCAN_TX.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructureCAN_TX.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_Init(GPIOB, &GPIO_InitStructureCAN_TX);
/* Connect CAN_RX & CAN_TX to AF9 */
GPIO_PinAFConfig(GPIOB, GPIO_PinSource12, GPIO_AF_CAN2); //CAN_RX = PB12
GPIO_PinAFConfig(GPIOB, GPIO_PinSource13, GPIO_AF_CAN2); //CAN_TX = PB13
}
void CAN_Configuration(void)
{
/* CAN2 reset */
CAN_DeInit(CAN2);
/* CAN2 configuration */
CAN_InitStructure.CAN_TTCM = DISABLE; // time-triggered communication mode = DISABLED
CAN_InitStructure.CAN_ABOM = DISABLE; // automatic bus-off management mode = DISABLED
CAN_InitStructure.CAN_AWUM = DISABLE; // automatic wake-up mode = DISABLED
CAN_InitStructure.CAN_NART = DISABLE; // non-automatic retransmission mode = DISABLED
CAN_InitStructure.CAN_RFLM = DISABLE; // receive FIFO locked mode = DISABLED
CAN_InitStructure.CAN_TXFP = DISABLE; // transmit FIFO priority = DISABLED
//CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack; // Debug can mode
CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack; // Debug can mode
CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; // synchronization jump width = 1
CAN_InitStructure.CAN_BS1 = CAN_BS1_12tq; //10
CAN_InitStructure.CAN_BS2 = CAN_BS2_2tq; //4
CAN_InitStructure.CAN_Prescaler = 6; // baudrate 500 kbps APB1 = 45MHz tq + tq*BS1 + tq*BS2 73%
CAN_Init(CAN2, &CAN_InitStructure);
}
void CAN_SetFilter(void)
{
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CAN_InitTypeDef CAN_InitStructure;
/* Default filter - accept all to CAN_FIFO*/
CAN_InitStructure.CAN_Mode = CAN_OperatingMode_Initialization; // Can to init mode
CAN_FilterInitStructure.CAN_FilterActivation = DISABLE; // Disable filter
CAN_FilterInitStructure.CAN_FilterNumber = 14; // 0..13 for CAN1, .27 for CAN2
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_FIFO0;
CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_16bit;
CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
// este nastavit 11 bitove ID
}
void CAN_SetNVIC(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
CAN_ITConfig(CAN2, CAN_IT_FMP0, ENABLE);
}
uint8_t CAN_Tq_CMD(int16_t torque)
{
CanTxMsg TxMessage;
TxMessage.StdId = REG_R_RX;
TxMessage.ExtId = 0x0;
TxMessage.RTR = CAN_RTR_DATA;
TxMessage.IDE = CAN_ID_STD;
TxMessage.DLC = 3;
TxMessage.Data[0] = REGID_TQ_CMD;
TxMessage.Data[1] = (uint8_t)torque;
TxMessage.Data[2] = (uint8_t)(torque>>8);
CAN_Transmit(CAN2, &TxMessage);
if(CAN_TransmitStatus(CAN2, 0)) return 0;
else return 1;
}
int16_t CAN_RxMessage(void)
{
CanRxMsg RxMessage;
int16_t torque = 0;
CAN_Receive(CAN2,CAN_FIFO0,&RxMessage);
if((RxMessage.Data[0]) == REGID_TQ_CMD)
{
torque |= RxMessage.Data[1];
torque |= RxMessage.Data[2]<<8;
}
return torque;
}
void initCan(void)
{
// Init clock
CAN_RCC_Configuration();
// Init GPIO pins
CAN_GPIO_Init();
// CAN Configuration
CAN_Configuration();
// Messages id configuration
CAN_SetFilter();
// Enable message interrupt
CAN_SetNVIC();
CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
CAN_Init(CAN2, &CAN_InitStructure);
}
#solved-can-normal-mode-problem #can-bus-normal-mode-problem-init #can #can
2014-01-31 04:02 PM
Are you sure the data rate and bit timing matches on both nodes? You need to match the bit rate and the timing window or you get a lot of errors. What does the error register show?
Both CAN pins should be no pull up. The transceiver manages the RX state all the time. A pullup interferes with it. Jack Peacock2014-01-31 04:27 PM
mcp2551 has pull up only on TXD. I think I should leave RXD at pullup. Baudrate and bit sampling should be ok. I calculated it and also it works well through can reader with my board in loopback mode.
After sending a normal mode message I get recessive bit error2014-02-01 02:25 PM
A recessive error can occur if the bus is not terminated. Do you have 120 ohm resistors at each end of the twisted-pair cable?
The MCP transceiver has a push-pull driver at the RxD pin, don't turn on the internal pull-up. Jack Peacock2014-02-01 03:21 PM
I had that problem before. Even with loopback mode I wasnt transimitting throught transciever. When I added terminating resistor it worked. So that shouldnt be the problem
Iam suspecting the problem is in the end of initCan function. Here Iam again initialising CAN (without previous deinitialisation). Even if I wont switch the mode, only initialisation alone cause recessive error. The problem may be just the method of switching to normal mode. How and when should this be done?Thank you2014-02-02 02:28 PM
Is there anything Iam doing wrong? I changed the location of normal mode initialisation by swaping it with loopback mode in can cofig function. Its still not working with same error but at least now there is no secondary error caused by reinitialisation.
I have even tried the library function for switching modes. It returned SUCESS. So I have read BTR register afterwards and loopback bit was set. Switching can to normal is really taking too long time to overcome.2014-02-03 01:50 AM
Change TX and RX as AF pull up, try following bit timing for 500kbps. 120 ohm resistor termination is necessary for 500kbps due to high speed data. Other code seems correct.
/* Configure CAN TX as alternate function pull-up */ GPIO_InitStructure.GPIO_Pin = CAN_TX_PIN[CAN]; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_CLOCK_SPEED; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(CAN_TX_PORT[CAN], &GPIO_InitStructure); /* Configure CAN RX as alternate function input pull-up */ GPIO_InitStructure.GPIO_Pin = CAN_RX_PIN[CAN]; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; GPIO_Init(CAN_RX_PORT[CAN], &GPIO_InitStructure); /* CAN Filter,FIFO and Baudrate settings */ CAN_DeInit(CAN_NO[CAN]); CAN_InitStructure.CAN_TTCM = DISABLE; // time-triggered communication mode = DISABLED CAN_InitStructure.CAN_ABOM = ENABLE; // automatic bus-off management mode =ENABLE
CAN_InitStructure.CAN_AWUM = ENABLE; // automatic wake-up mode =ENABLE
CAN_InitStructure.CAN_NART = DISABLE; // non-automatic retransmission mode = DISABLED CAN_InitStructure.CAN_RFLM = DISABLE; // receive FIFO locked mode = DISABLED CAN_InitStructure.CAN_TXFP = DISABLE; // transmit FIFO priority = DISABLED CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;//CAN_Mode_LoopBack;// CAN_Mode_Normal; /* CAN Baudrate = 500kbps (APB1 clock and CAN clock is 42MHz) ** CAN_Prescaler value= CAN_clock/(required_Baudrate*total_number_of_tq) ** In present case, total_number_of_tq=CAN_SJW_1tq+CAN_BS1_2tq+CAN_BS2_5tq=8*tq ** so CAN_Prescaler= 42MHz/(500kbps*12)=7 CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq; CAN_InitStructure.CAN_BS2 = CAN_BS2_8tq; CAN_InitStructure.CAN_Prescaler = 7; CAN_Init(CAN_NO[CAN], &CAN_InitStructure);2014-02-03 03:21 AM
Dont see any difference that would be causing it. I think the problem might be that at the end of initialisation I call CAN_OperatingModeRequest(CAN2, CAN_OperatingMode_Normal);
returning sucess but actually in BTR register Iam still in loopback mode. Its interesting for me. I dont know whats going on.2014-02-09 03:26 PM
*SOLVED*
It wasnt a software issue but HW issue. Level converter from transciever RX couldnt support enough current to overcome capacitance in that part so the RX data were disorted. It caused the recessive error.Atleast this wasnt completely stupid issue.Anyway thanks all for replay :)