2018-04-23 08:15 AM
Hello everyone, I am trying to configure my CAN on my OLIMEXINO STM32 board :
https://www.olimex.com/Products/Duino/STM32/OLIMEXINO-STM32/
(with a STM32F103RBT6 �C), but it just won't work ...I'm using a PCAN USB to communicate between my PC and my board, but there is no data exchange between my board and my computer. The Pcan software is sending me a 'bus heavy' flag and I don't know why.
Here is my code :
int nb_trames = 4;
int ID[8] = {0x06, 0x11, 0x12, 0x13, 0x14,0x15,0x16,0x17}; Tab_TxMessages = malloc(nb_trames * sizeof(CanTxMsgTypeDef));...
while (1)
{int cpt = 0 ;
for (cpt = 0 ; cpt < nb_trames ; cpt++)
{ Tab_TxMessages[cpt].StdId = ID[cpt]; Tab_TxMessages[cpt].IDE = 0; Tab_TxMessages[cpt].RTR = 0; Tab_TxMessages[cpt].DLC = 8; Tab_TxMessages[cpt].Data[0] = cpt; Tab_TxMessages[cpt].Data[1] = cpt+1; Tab_TxMessages[cpt].Data[2] = cpt+2; Tab_TxMessages[cpt].Data[3] = cpt+3; Tab_TxMessages[cpt].Data[4] = cpt+4; Tab_TxMessages[cpt].Data[5] = cpt+5; Tab_TxMessages[cpt].Data[6] = cpt+6; Tab_TxMessages[cpt].Data[7] = cpt+7; HAL_CAN_Transmit(&hcan, HAL_MAX_DELAY); HAL_Delay(1); }}
(don't know how to properly format it though, if anyone can help...)
The issue is not coming from the 120 Ohm (I set the jumper correctly on the board). However it might come from the way I configure my CAN bus :
void MX_CAN_Init(void)
{hcan.Instance = CAN1;
hcan.Init.Prescaler = 4; hcan.Init.Mode = CAN_MODE_NORMAL; hcan.Init.SJW = CAN_SJW_1TQ; hcan.Init.BS1 = CAN_BS1_8TQ; hcan.Init.BS2 = CAN_BS2_8TQ; hcan.Init.TTCM = DISABLE; hcan.Init.ABOM = DISABLE; hcan.Init.AWUM = DISABLE; hcan.Init.NART = DISABLE; hcan.Init.RFLM = DISABLE; hcan.Init.TXFP = DISABLE; if (HAL_CAN_Init(&hcan) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); }}
I have no idea how to correctly configure it, so if anyone dare to explain, that might help solve the issue..
Thank you for the help !
#pcan #can-interface #olimex #stm32f103rbt62018-04-24 03:34 AM
Go with the debugger and inspect the CAN device status when the code get stuck (register TSR is essential).
2018-04-24 04:12 AM
So when it get stuck, TSR = 0x19000008
it means that : - No transmit request pending for mailbox 1 and 2
- CODE : 01
- Transmission error for mailbox 0 (and obviously last transmission not OK)
Another register changes when it gets stuck : MSR = 0x108 (sometimes 0xD08 or 0xC08)
0x108 means that :
- The CAN hardware is currently transmitter
- This bit is set by hardware to signal that a SOF bit has been detected while the CAN
hardware was in Sleep mode. Setting this bit generates a status change interrupt if theWKUIE bit in the CAN_IER register is set.This bit is cleared by software.0xD08 means that :
-CAN_RX pin is '1'
-The value of RX on the last sample point (current received bit value) is also '1'
- and same thing as 0x108
0xc08 means that :
-CAN_RX pin is '1'
-The value of RX on the last sample point (current received bit value) is also '1'
- This bit is set by hardware to signal that a SOF bit has been detected while the CAN
hardware was in Sleep mode. Setting this bit generates a status change interrupt if theWKUIE bit in the CAN_IER register is set.This bit is cleared by software.2018-04-24 04:36 AM
So the controller detects a transmit error.
One explanation could be that the controller failed to read back from Rx the level forced on Tx.
Can you check CAN_CTRL signal ?
If I remember correctly, the other end must acknowledge the message, so you have to make sure that speed is ok ? Did you changed your settings (BS1, BS2) ?
2018-04-24 04:52 AM
I don't find any CAN_CTRL register, so I guess you mean CAN_MCR (Master Control Register).
It's value is : 0x10040
- CAN reception/transmission frozen during debug. Reception FIFOs can still be
accessed/controlled normally.- master reset : normal operation
- Time Triggered Communication mode disabled.
- The Bus-Off state is left automatically by hardware once 128 occurrences of 11 recessive
bits have been monitored.- The Sleep mode is left on software request by clearing the SLEEP bit of the CAN_MCR
register.- The CAN hardware will automatically retransmit the message until it has been
successfully transmitted according to the CAN standard.- Receive FIFO not locked on overrun. Once a receive FIFO is full the next incoming
message will overwrite the previous one.- This bit controls the transmission order when several mailboxes are pending at the same
time.0: Priority driven by the identifier of the message- not in sleep mode
yes, I tried with your settings (BS1 11 TQ and BS2 6 TQ) and tried with mine (8 TQ and 8 TQ), the only difference there is is that with your settings my CAN monitor on my computer directly says BUSHEAVY and with my settings it says OK for a while and the BUSHEAVY, but on both cases no data is being transmitted.
EDIT : It's the ABOM bit that appears to drive the BUSHEAVY thing, if I disable it it stays on OK state. However I still don't receive any data
Speed is also ok, tried with both 1Mb/s and 500 kb/s, nothing changes.
2018-04-24 05:22 AM
I can't find how to do it (other than checking it on the board with an oscilloscope but I don't have one ..)
2018-04-24 08:11 AM
drop your speed down below the normal maximum of 250KHz, after you have it working, then you can try to go faster.
HAL_DELAY (1) is that 1 mS ?
can you wait a little bit longer, what is the hurry ?
after you get it working, you can work on the slow bits..
where are you up to ?
You should be working on the receiver first..
Can you receive ?
Drop your speed and recheck.
2018-04-24 10:21 AM
T J wrote:
HAL_DELAY (1) is that 1 mS ?
can you wait a little bit longer, what is the hurry ?
Yes it's 1 ms, there was no hurry, actually I tried commenting it after posting here, but nothing changed.
I tried with 250 kb/s but nothing changed, also changed the delay to 100 ms, same result.
I haven't tried receiving yet, but I'll give it a go
T J wrote:
where are you up to ?
What do you mean ? In the project ? I am basically just trying to send a bunch of data over CAN that's all.
2018-04-24 10:36 AM
Stick to 250KHz or below to start,
make the receiver work first.
here is my receiver section outside the cube init
I use 32bit frame buffers, so the interrupt time is much reduced.
caninit:
__HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP1);
__HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP0);void CEC_CAN_IRQHandler(void) {
/* USER CODE BEGIN CEC_CAN_IRQn 0 */ CAN_IRQFlag = true; checkCanRxFifos(); /* USER CODE END CEC_CAN_IRQn 0 */ HAL_CAN_IRQHandler(&hcan); /* USER CODE BEGIN CEC_CAN_IRQn 1 *//* USER CODE END CEC_CAN_IRQn 1 */
}void checkCanRxFifos(void) {
int readCanBytecount; char canFifo1FullFlag = CAN->RF1R & CAN_RF1R_FMP1; if (canFifo1FullFlag) { { readCanBytecount = (CAN->sFIFOMailBox[1].RDTR & 0x0f);canRxMsgBottomWord[canRxMsgIN] = CAN->sFIFOMailBox[1].RDLR;
canRxMsgTopWord[canRxMsgIN] = CAN->sFIFOMailBox[1].RDHR;canRxMsgID[canRxMsgIN] = CAN->sFIFOMailBox[1].RIR >> 21;
CAN->RF1R |= CAN_RF1R_RFOM1; // release FIFOcanRxMsgLength[canRxMsgIN] = readCanBytecount;
canRxMsgIN++;
canRxMsgIN &= 0x3F; // 64 entries only canRxMsgTableEMPTY = false; if (canRxMsgIN == canRxMsgOUT) canRxMsgTableFULL = true; } CAN->IER |= CAN_IER_FMPIE1; // (11) Set FIFO1 message pending IT enable }char canFifo0FullFlag = CAN->RF0R & CAN_RF0R_FMP0;
if (canFifo0FullFlag) { { readCanBytecount = (CAN->sFIFOMailBox[0].RDTR & 0x0f);canRxMsgBottomWord[canRxMsgIN] = CAN->sFIFOMailBox[0].RDLR;
canRxMsgTopWord[canRxMsgIN] = CAN->sFIFOMailBox[0].RDHR;uint32_t canRxmsgID = CAN->sFIFOMailBox[0].RIR >> 21;
CAN->RF0R |= CAN_RF0R_RFOM0; // release FIFOif(canRxMsgTableFULL) {
canRxMsgTableOverflow = true; // now dump new frame... }else { canRxMsgID[canRxMsgIN] = canRxmsgID; canRxMsgLength[canRxMsgIN] = readCanBytecount; canRxMsgIN++; canRxMsgIN &= 0x3F; // 64 entries only canRxMsgTableEMPTY = false; if (canRxMsgIN == canRxMsgOUT) canRxMsgTableFULL = true; } //length = sprintf(string + length,'%08X, %08X :W',canFifoBuf.d32[0],canFifoBuf.d32[1]); // for( int i = 0; i < readCanBytecount; i++){ // canRxBuffer[canRxpointerIN++] = canFifoBuf.d8[i]; // canRxpointerIN &= 0xFF; // if (canRxpointerIN == canRxpointerOUT ) CanRxbufferOverrun = true; // //length += sprintf(string + length,'%02X, ',canFifoBuf.d8[i]); // } //sprintf(string + length -2,'\n\r'); // remove 2 bytes, the last comma and space } CAN->IER |= CAN_IER_FMPIE0; // (11) Set FIFO1 message pending IT enable } // if (length >0) puts(string);}
2018-04-25 05:30 AM
I am facing the same issue when I try to do the receive part, it gets stuck within the same kind of loop :
while(__HAL_CAN_MSG_PENDING(hcan, FIFONumber) == 0U)
{ /* Check for the Timeout */ if(Timeout != HAL_MAX_DELAY) { if((Timeout == 0U) || ((HAL_GetTick()-tickstart) > Timeout)) { hcan->State = HAL_CAN_STATE_TIMEOUT; /* Process unlocked */ __HAL_UNLOCK(hcan); return HAL_TIMEOUT; } } }2018-04-25 05:56 AM
I just figured that whenever my bus is OK in PCANview, if I try to send any data through it (via the computer) it gets in 'bus-off' state..