I'm trying to set up a 33333 bus that uses a single wire for can. Took a bit to get the 33333 configured but now it seems to have issues with receiving. Putting a break point at CAN2_SignalObjectEvent's checks never triggers. This set up below is for a dual wire CAN, do I need to combine the RX/TX to make it work for single wire? How would I go about this?
#define CAN_CONTROLLER2 1 // CAN Controller number (can 1 is pa12/11) (can 2 is pb12/13) //------------------------------------------------------------------------------ #define _CAN_Driver_(n) Driver_CAN##n #define CAN_Driver_(n) _CAN_Driver_(n) extern ARM_DRIVER_CAN CAN_Driver_(CAN_CONTROLLER2); #define ptrCAN (&CAN_Driver_(CAN_CONTROLLER2)) 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 int ID_Read; static int _TIMEOUT = 100;//each 100 is a second 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 receive event if (obj_idx == rx2_obj_idx) { // If receive object event ptrCAN->MessageRead(rx2_obj_idx, &rx2_msg_info, rx2_data, 8U); ID_Read = rx2_msg_info.id; printf("single caught:ID_Read &i \n", ID_Read); } } if (event == ARM_CAN_EVENT_SEND_COMPLETE) { if (obj_idx == tx2_obj_idx) { } } } 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 % (10U*CAN_BITRATE_NOMINAL)) <= 300U) { status = ptrCAN->SetBitrate (ARM_CAN_BITRATE_NOMINAL, CAN_BITRATE_NOMINAL, ARM_CAN_BIT_PROP_SEG (1U) | ARM_CAN_BIT_PHASE_SEG1(5U) | ARM_CAN_BIT_PHASE_SEG2(3U) | ARM_CAN_BIT_SJW (1U)); } else 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 CANWrite_MS (int ECU, unsigned char data[], char noReply) { _LEDON (BLUE); osDelay(1);_LEDOFF (BLUE); // sendCompleted=false; if (!noReply) ID_Read=0; 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); } long CANRead_MS (int ECU, unsigned char data, char position) { memset(&command_Data, 0U, 8); for (int t=0;t <_TIMEOUT;t++) { osDelay(10); printf("read:ID_Read &i \n", ID_Read); if (ID_Read > 0) { if (ECU == 0 ) { memcpy(&command_Data, &rx2_data,8); if (data != 0) { if (command_Data[position] == data) return ID_Read; } else return ID_Read;
I do appreciate the insight.
Unless I'm missing something I don't see how it's a car bus issue because the car is doing as it should. Maybe I mis-explained that? The car does accept the data from the single wire and it does reply. The fault lay with the code as far as I can determine with sniffing. Even the analyzer I have shows the data past the transceiver (from arm to transceiver). So the reply packets are getting that far. It could be a weak logic level I guess. The transceiver is powered by 5 volts. My analyzer does have an analog mode I can see what levels it reaches. I'll keep this all in mind and not omit hardware as a possibility. thx.
I'll reach back once I have more information.
As you predicted it was hardware. Turns out my debug unit needed to be grounded to the car for it to work. The difference in ground potentials was upsetting something.
It's nice to hear that you solved the problem!
Best regards, Milorad