This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

stumped with second can channel event.

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;
}


Parents
  • 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

Reply
  • 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

Children