I have a st32f205 and set up both Can 1&2.
Can 1, will send and receive. Can 2, will send, not receive.
I can see the data with a tool, so I know the data is on the wire but the ARM_CAN_EVENT_RECEIVE will not pick it up. The ARM_CAN_EVENT_SEND_COMPLETE is working fine.
Here is my can2 had to remove all comments to fit in post. What could I have done wrong?
#define CAN_CONTROLLER 2 #define _CA_Driver_(n) Driver_CAN##n #define CAN_Driver_(n) _CAN_Driver_(n) extern ARM_DRIVER_CAN CAN_Driver_(CAN_CONTROLLER); #define ptrCAN (&CAN_Driver_(CAN_CONTROLLER)) uint32_t rx1_obj_idx; uint8_t rx1_data[8]; ARM_CAN_MSG_INFO rx1_msg_info; uint32_t tx1_obj_idx; uint8_t tx1_data[8]; ARM_CAN_MSG_INFO tx1_msg_info; static bool sendCompleted = false; static int ID_Read; static int _TIMEOUT = 100; void CAN1_SignalUnitEvent (uint32_t event) { switch (event) { case ARM_CAN_EVENT_UNIT_ACTIVE: break; case ARM_CAN_EVENT_UNIT_WARNING: break; case ARM_CAN_EVENT_UNIT_PASSIVE: break; case ARM_CAN_EVENT_UNIT_BUS_OFF: break; } } void CAN1_SignalObjectEvent (uint32_t obj_idx, uint32_t event) { if (event == ARM_CAN_EVENT_RECEIVE) { if (obj_idx == rx1_obj_idx) { ptrCAN->MessageRead(rx1_obj_idx, &rx1_msg_info, rx1_data, 8U); ID_Read = rx1_msg_info.id; } } if (event == ARM_CAN_EVENT_SEND_COMPLETE) { if (obj_idx == tx1_obj_idx) { sendCompleted=true; } } } bool CAN1_Initialize (int CAN_BITRATE_NOMINAL) { ARM_CAN_CAPABILITIES can_cap; ARM_CAN_OBJ_CAPABILITIES can_obj_cap; int32_t status; uint32_t i, num_objects, clock; can_cap = ptrCAN->GetCapabilities (); num_objects = can_cap.num_objects; status = ptrCAN->Initialize (CAN1_SignalUnitEvent, CAN1_SignalObjectEvent); if (status != ARM_DRIVER_OK) { return false; } status = ptrCAN->PowerControl (ARM_POWER_FULL); if (status != ARM_DRIVER_OK) { return false; } status = ptrCAN->SetMode (ARM_CAN_MODE_INITIALIZATION); if (status != ARM_DRIVER_OK) { return false; } clock = ptrCAN->GetClock(); if ((clock % (8U*CAN_BITRATE_NOMINAL)) == 0U) { status = ptrCAN->SetBitrate (ARM_CAN_BITRATE_NOMINAL, CAN_BITRATE_NOMINAL, ARM_CAN_BIT_PROP_SEG (5U) | ARM_CAN_BIT_PHASE_SEG1(1U) | ARM_CAN_BIT_PHASE_SEG2(1U) | ARM_CAN_BIT_SJW (1U)); } else if ((clock % (10U*CAN_BITRATE_NOMINAL)) == 0U) { status = ptrCAN->SetBitrate (ARM_CAN_BITRATE_NOMINAL, CAN_BITRATE_NOMINAL, ARM_CAN_BIT_PROP_SEG (7U) | ARM_CAN_BIT_PHASE_SEG1(1U) | ARM_CAN_BIT_PHASE_SEG2(1U) | ARM_CAN_BIT_SJW (1U)); } else if ((clock % (12U*CAN_BITRATE_NOMINAL)) == 0U) { status = ptrCAN->SetBitrate (ARM_CAN_BITRATE_NOMINAL, CAN_BITRATE_NOMINAL, ARM_CAN_BIT_PROP_SEG (7U) | ARM_CAN_BIT_PHASE_SEG1(2U) | ARM_CAN_BIT_PHASE_SEG2(2U) | ARM_CAN_BIT_SJW (2U)); } else { return false; } if (status != ARM_DRIVER_OK) { return false; } rx1_obj_idx = 0xFFFFFFFFU; tx1_obj_idx = 0xFFFFFFFFU; for (i = 0U; i < num_objects; i++) { can_obj_cap = ptrCAN->ObjectGetCapabilities (i); if ((rx1_obj_idx == 0xFFFFFFFFU) && (can_obj_cap.rx == 1U)) { rx1_obj_idx = i; } else if ((tx1_obj_idx == 0xFFFFFFFFU) && (can_obj_cap.tx == 1U)) { tx1_obj_idx = i; break; } } if ((rx1_obj_idx == 0xFFFFFFFFU) || (tx1_obj_idx == 0xFFFFFFFFU)) { return false; } status = ptrCAN->ObjectSetFilter(rx1_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, 0xfff, 0U); if (status != ARM_DRIVER_OK) { return false; } status = ptrCAN->ObjectConfigure(tx1_obj_idx, ARM_CAN_OBJ_TX); if (status != ARM_DRIVER_OK) { return false; } status = ptrCAN->ObjectConfigure(rx1_obj_idx, ARM_CAN_OBJ_RX); if (status != ARM_DRIVER_OK) { return false; } status = ptrCAN->SetMode (ARM_CAN_MODE_NORMAL); if (status != ARM_DRIVER_OK) { return false; } return true; } void setFilters_HS(long ID1, long ID2, long ID3, long ID4, long ID5) { ptrCAN->SetMode (ARM_CAN_MODE_INITIALIZATION); ptrCAN->ObjectSetFilter(rx1_obj_idx, ARM_CAN_FILTER_ID_RANGE_REMOVE , 0x100, 0xfff); if (ID1 > 0) ptrCAN->ObjectSetFilter(rx1_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ID1, 0U); if (ID2 > 0) ptrCAN->ObjectSetFilter(rx1_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ID2, 0U); if (ID3 > 0) ptrCAN->ObjectSetFilter(rx1_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ID3, 0U); if (ID4 > 0) ptrCAN->ObjectSetFilter(rx1_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ID4, 0U); if (ID5 > 0) ptrCAN->ObjectSetFilter(rx1_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ID5, 0U); ptrCAN->SetMode (ARM_CAN_MODE_NORMAL); } void CANWrite_HS (int ECU, unsigned char data[]) { sendCompleted=false; ID_Read=0; memset(&rx1_data, 0U, 8); memset(&tx1_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO)); tx1_msg_info.id = ECU; ptrCAN->MessageSend(tx1_obj_idx, &tx1_msg_info, data, 8U); } int CANRead_HS (int ECU, unsigned char data, char position) { memset(&command_Data, 0U, 8); for (int t=0;t <_TIMEOUT;t++) { osDelay(10); if (ID_Read > 0) { if (ECU == 0 ) { memcpy(&command_Data, &rx1_data,8); if (data != 0) { if (command_Data[position] == data) return 1; } else return 1; } if (ECU == ID_Read) { memcpy(&command_Data, &rx1_data,8); if (data != 0) { if (command_Data[position] == data) return 1; } else return 1; } } } return 0; }
sorry that was the working Can. Here is the effected.
#define CAN_CONTROLLER 1 #define _CAN_Driver_(n) Driver_CAN##n #define CAN_Driver_(n) _CAN_Driver_(n) extern ARM_DRIVER_CAN CAN_Driver_(CAN_CONTROLLER); #define ptrCAN (&CAN_Driver_(CAN_CONTROLLER)) uint32_t rx2_obj_idx; uint8_t rx2_data[8]; ARM_CAN_MSG_INFO rx2_msg_info; uint32_t tx2_obj_idx; uint8_t tx2_data[8]; ARM_CAN_MSG_INFO tx2_msg_info; static bool sendCompleted = false; static int ID_Read; static int _TIMEOUT = 100; void CAN2_SignalUnitEvent (uint32_t event) { switch (event) { case ARM_CAN_EVENT_UNIT_ACTIVE: break; case ARM_CAN_EVENT_UNIT_WARNING: break; case ARM_CAN_EVENT_UNIT_PASSIVE: break; case ARM_CAN_EVENT_UNIT_BUS_OFF: break; } } void CAN2_SignalObjectEvent (uint32_t obj_idx, uint32_t event) { if (event == ARM_CAN_EVENT_RECEIVE) { if (obj_idx == rx2_obj_idx) { ptrCAN->MessageRead(rx2_obj_idx, &rx2_msg_info, rx2_data, 8U); ID_Read = rx2_msg_info.id; printf("rx2_data %i,%i,%i,%i,%i,%i,%i,%i,",rx2_data[0],rx2_data[1],rx2_data[2],rx2_data[3],rx2_data[4],rx2_data[5],rx2_data[6],rx2_data[7]); } } if (event == ARM_CAN_EVENT_SEND_COMPLETE) { if (obj_idx == tx2_obj_idx) { sendCompleted=true; } } } bool CAN2_Initialize (int CAN_BITRATE_NOMINAL) { ARM_CAN_CAPABILITIES can_cap; ARM_CAN_OBJ_CAPABILITIES can_obj_cap; int32_t status; uint32_t i, num_objects, clock; can_cap = ptrCAN->GetCapabilities (); num_objects = can_cap.num_objects; status = ptrCAN->Initialize (CAN2_SignalUnitEvent, CAN2_SignalObjectEvent); if (status != ARM_DRIVER_OK) { return false; } status = ptrCAN->PowerControl (ARM_POWER_FULL); if (status != ARM_DRIVER_OK) { return false; } status = ptrCAN->SetMode (ARM_CAN_MODE_INITIALIZATION); if (status != ARM_DRIVER_OK) { return false; } clock = ptrCAN->GetClock(); if ((clock % (8U*CAN_BITRATE_NOMINAL)) == 0U) { status = ptrCAN->SetBitrate (ARM_CAN_BITRATE_NOMINAL, CAN_BITRATE_NOMINAL, ARM_CAN_BIT_PROP_SEG (5U) | ARM_CAN_BIT_PHASE_SEG1(1U) | ARM_CAN_BIT_PHASE_SEG2(1U) | ARM_CAN_BIT_SJW (1U)); } else if ((clock % (10U*CAN_BITRATE_NOMINAL)) == 0U) { status = ptrCAN->SetBitrate (ARM_CAN_BITRATE_NOMINAL, CAN_BITRATE_NOMINAL, ARM_CAN_BIT_PROP_SEG (7U) | ARM_CAN_BIT_PHASE_SEG1(1U) | ARM_CAN_BIT_PHASE_SEG2(1U) | ARM_CAN_BIT_SJW (1U)); } else if ((clock % (12U*CAN_BITRATE_NOMINAL)) == 0U) { status = ptrCAN->SetBitrate (ARM_CAN_BITRATE_NOMINAL, CAN_BITRATE_NOMINAL, ARM_CAN_BIT_PROP_SEG (7U) | ARM_CAN_BIT_PHASE_SEG1(2U) | ARM_CAN_BIT_PHASE_SEG2(2U) | ARM_CAN_BIT_SJW (2U)); } else { return false; } if (status != ARM_DRIVER_OK) { return false; } rx2_obj_idx = 0xFFFFFFFFU; tx2_obj_idx = 0xFFFFFFFFU; for (i = 0U; i < num_objects; i++) { can_obj_cap = ptrCAN->ObjectGetCapabilities (i); if ((rx2_obj_idx == 0xFFFFFFFFU) && (can_obj_cap.rx == 1U)) { rx2_obj_idx = i; } else if ((tx2_obj_idx == 0xFFFFFFFFU) && (can_obj_cap.tx == 1U)) { tx2_obj_idx = i; break; } } if ((rx2_obj_idx == 0xFFFFFFFFU) || (tx2_obj_idx == 0xFFFFFFFFU)) { return false; } status = ptrCAN->ObjectSetFilter(rx2_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, 0xfff, 0U); if (status != ARM_DRIVER_OK) { return false; } status = ptrCAN->ObjectConfigure(tx2_obj_idx, ARM_CAN_OBJ_TX); if (status != ARM_DRIVER_OK) { return false; } status = ptrCAN->ObjectConfigure(rx2_obj_idx, ARM_CAN_OBJ_RX); if (status != ARM_DRIVER_OK) { return false; } status = ptrCAN->SetMode (ARM_CAN_MODE_NORMAL); if (status != ARM_DRIVER_OK) { return false; } return true; } void setFilters_MS(long ID1, long ID2, long ID3, long ID4, long ID5) { printf("set mode for MS can: %i\n",rx2_obj_idx); ptrCAN->SetMode (ARM_CAN_MODE_INITIALIZATION); ptrCAN->ObjectSetFilter(rx2_obj_idx, ARM_CAN_FILTER_ID_RANGE_REMOVE , 0x100, 0xfff);//clear all. if (ID1 > 0) ptrCAN->ObjectSetFilter(tx2_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ID1, 0U); if (ID2 > 0) ptrCAN->ObjectSetFilter(tx2_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ID2, 0U); if (ID3 > 0) ptrCAN->ObjectSetFilter(tx2_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ID3, 0U); if (ID4 > 0) ptrCAN->ObjectSetFilter(tx2_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ID4, 0U); if (ID5 > 0) ptrCAN->ObjectSetFilter(tx2_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ID5, 0U); ptrCAN->SetMode (ARM_CAN_MODE_NORMAL); } void CANWrite_MS (int ECU, unsigned char data[]) { printf("write for MS can: %i\n",rx2_obj_idx); sendCompleted=false; ID_Read=0;//// prepare the read data for this send. memset(&rx2_data, 0U, 8);//clear data. memset(&tx2_msg_info, 0U, sizeof(ARM_CAN_MSG_INFO)); tx2_msg_info.id = ECU; ptrCAN->MessageSend(tx2_obj_idx, &tx2_msg_info, data, 8U); } int CANRead_MS (int ECU, unsigned char data, char position) { memset(&command_Data, 0U, 8); for (int t=0;t <_TIMEOUT;t++) { osDelay(10); if (ID_Read > 0) { if (ECU == 0 ) { memcpy(&command_Data, &rx2_data,8); if (data != 0) { if (command_Data[position] == data) return 1; } else return 1; } if (ECU == ID_Read) { memcpy(&command_Data, &rx2_data,8); if (data != 0) { if (command_Data[position] == data) return 1; } else return 1; } } } return 0; }
Hi,
first, I suggest you try c:\Keil\ARM\PACK\Keil\STM32F2xx_DFP\2.7.0\MDK\Boards\Keil\MCBSTM32F200\Middleware\CAN\CAN\ example and in CAN.c file change:
#define CAN_CONTROLLER 1 // CAN Controller number #define CAN_LOOPBACK 1 // 0 = no loopback, 1 = external loopback
to
#define CAN_CONTROLLER 2 // CAN Controller number #define CAN_LOOPBACK 0 // 0 = no loopback, 1 = external loopback
after that try if it works as expected, of course if your hardware is different then MCBSTM32F200 adapt pins and clock if necessary, if it works, you can continue from there.
I have tried that and it works, it receives data from CAN bus on CAN2 controller.
BTW,
ptrCAN->ObjectSetFilter(rx2_obj_idx, ARM_CAN_FILTER_ID_RANGE_REMOVE , 0x100, 0xfff);//clear all.
does not do what you expect, it would remove the range filter previously set it does not remove all filters that were added as exact. You have to remove any exact filter by calling
ObjectSetFilter(idx, ARM_CAN_FILTER_ID_EXACT_REMOVE, ID, 0U);
Best regrads, Milorad
So removing must be done one by one? That may be my issue. I will also try changing channels.
Problem was right there this entire time. Just didnt see it.
if (ID1 > 0) ptrCAN->ObjectSetFilter(tx2_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ID1, 0U); if (ID2 > 0) ptrCAN->ObjectSetFilter(tx2_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ID2, 0U); if (ID3 > 0) ptrCAN->ObjectSetFilter(tx2_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ID3, 0U); if (ID4 > 0) ptrCAN->ObjectSetFilter(tx2_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ID4, 0U); if (ID5 > 0) ptrCAN->ObjectSetFilter(tx2_obj_idx, ARM_CAN_FILTER_ID_EXACT_ADD, ID5, 0U);
tx2_obj_idx is not going to work for a filter... Somehow I had tx instead of rx.
I thought you were trying to see if anyone read your posts. That line stood out like a sore thumb.