⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcan_usb_kernel.c

📁 linux下的CAN BUS驱动代码。适合在arm平台使用。
💻 C
📖 第 1 页 / 共 3 页
字号:
  return pcan_hw_setcontrol_urb(dev, 1, 2, param0, param1,                            dummy, dummy, dummy, dummy, dummy, dummy,                           dummy, dummy, dummy, dummy, dummy, dummy);}int pcan_hw_SetCANOn(struct pcandev *dev){  u8  dummy  = 0;  DPRINTK(KERN_DEBUG "%s: pcan_hw_SetCANOn()\n", DEVICE_NAME);   return pcan_hw_setcontrol_urb(dev, 3, 2, 1, dummy,                            dummy, dummy, dummy, dummy, dummy, dummy,                           dummy, dummy, dummy, dummy, dummy, dummy);}int pcan_hw_SetCANOff(struct pcandev *dev){  int err;  u8  dummy  = 0;  DPRINTK(KERN_DEBUG "%s: pcan_hw_SetCANOff()\n", DEVICE_NAME);   err = pcan_hw_setcontrol_urb(dev, 3, 2, 0, dummy,                            dummy, dummy, dummy, dummy, dummy, dummy,                           dummy, dummy, dummy, dummy, dummy, dummy);  return err;}static int pcan_hw_SetCANSilentOn(struct pcandev *dev){  u8  dummy  = 0;  DPRINTK(KERN_DEBUG "%s: pcan_hw_SetCANSilentOn()\n", DEVICE_NAME);   return pcan_hw_setcontrol_urb(dev, 3, 3, 1, dummy,                            dummy, dummy, dummy, dummy, dummy, dummy,                           dummy, dummy, dummy, dummy, dummy, dummy);}static int pcan_hw_SetCANSilentOff(struct pcandev *dev){  u8  dummy  = 0;  DPRINTK(KERN_DEBUG "%s: pcan_hw_SetCANSilentOff()\n", DEVICE_NAME);   return pcan_hw_setcontrol_urb(dev, 3, 3, 0, dummy,                            dummy, dummy, dummy, dummy, dummy, dummy,                           dummy, dummy, dummy, dummy, dummy, dummy);}int pcan_hw_getBTR0BTR1(struct pcandev *dev, u16 *pwBTR0BTR1){  int err;  u8  dummy  = 0;  u8  param0 = 0;  u8  param1 = 0;  DPRINTK(KERN_DEBUG "%s: pcan_hw_getBTR0BTR1()\n", DEVICE_NAME);   err = pcan_hw_getcontrol_urb(dev, 1, 1, &param0, &param1, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy);  *pwBTR0BTR1 = param1;  *pwBTR0BTR1 <<= 8;  *pwBTR0BTR1 |= param0;  DPRINTK(KERN_DEBUG "%s: BTR0BTR1 = 0x%04x\n", DEVICE_NAME, *pwBTR0BTR1);   return err;}int pcan_hw_getQuartz(struct pcandev *dev, u32 *pdwQuartzHz){  int err = 0;  u8  dummy  = 0;  u8  param0 = 0;  DPRINTK(KERN_DEBUG "%s: pcan_hw_getQuartz()\n", DEVICE_NAME);   err = pcan_hw_getcontrol_urb(dev, 2, 1, &param0, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy);  *pdwQuartzHz = param0;  *pdwQuartzHz *= 1000000L;  DPRINTK(KERN_DEBUG "%s: Frequenz = %u\n", DEVICE_NAME, *pdwQuartzHz);     return err;}int pcan_hw_getAnything(struct pcandev *dev, u8 ucFunction, u8 ucNumber){  int err = 0;  u8  dummy[8];  int i;  DPRINTK(KERN_DEBUG "%s: pcan_hw_getAnything()\n", DEVICE_NAME);   for (i = 0; i < 7; i++)    dummy[i] = 0;  err = pcan_hw_getcontrol_urb(dev, ucFunction, ucNumber,                           &dummy[0], &dummy[1], &dummy[2], &dummy[3], &dummy[4], &dummy[5], &dummy[6], &dummy[7]);  DPRINTK(KERN_DEBUG "%s: Fun/Num:%d/%d  0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x\n", DEVICE_NAME,          ucFunction, ucNumber, dummy[0], dummy[1], dummy[2], dummy[3], dummy[4], dummy[5], dummy[6], dummy[7]);   return err;}int pcan_hw_getDeviceNr(struct pcandev *dev, u8 *pucDeviceNr){  int err;  u8  dummy  = 0;  DPRINTK(KERN_DEBUG "%s: pcan_hw_getDeviceNr()\n", DEVICE_NAME);   err = pcan_hw_getcontrol_urb(dev, 4, 1, pucDeviceNr, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy, &dummy);  DPRINTK(KERN_DEBUG "%s: DeviceNr = 0x%02x\n", DEVICE_NAME, *pucDeviceNr);   return err;}int pcan_hw_SetExtVCCOn(struct pcandev *dev){  u8  dummy  = 0;  DPRINTK(KERN_DEBUG "%s: pcan_hw_SetExtVCCOn()\n", DEVICE_NAME);   return pcan_hw_setcontrol_urb(dev, 0xA, 2, 1, dummy,                            dummy, dummy, dummy, dummy, dummy, dummy,                           dummy, dummy, dummy, dummy, dummy, dummy);}int pcan_hw_SetDeviceNr(struct pcandev *dev, u8 ucDeviceNr){  u8  dummy  = 0;  DPRINTK(KERN_DEBUG "%s: pcan_hw_SetDeviceNr()\n", DEVICE_NAME);   return pcan_hw_setcontrol_urb(dev, 4, 2, ucDeviceNr, dummy,                            dummy, dummy, dummy, dummy, dummy, dummy,                           dummy, dummy, dummy, dummy, dummy, dummy);}int pcan_hw_SetSNR(struct pcandev *dev, u32 dwSNR){  u8  dummy  = 0;  DPRINTK(KERN_DEBUG "%s: pcan_hw_SetSNR()\n", DEVICE_NAME);   return pcan_hw_setcontrol_urb(dev, 6, 2,                            (u8)( dwSNR        & 0xff),                            (u8)((dwSNR >>  8) & 0xff),                            (u8)((dwSNR >> 16) & 0xff),                            (u8)((dwSNR >> 24) & 0xff),                            dummy, dummy, dummy, dummy, dummy,                           dummy, dummy, dummy, dummy, dummy);}static int pcan_hw_SetExtVCCOff(struct pcandev *dev){  u8  dummy  = 0;  DPRINTK(KERN_DEBUG "%s: pcan_hw_SetExtVCCOff()\n", DEVICE_NAME);   return pcan_hw_setcontrol_urb(dev, 0xA, 2, 0, dummy,                            dummy, dummy, dummy, dummy, dummy, dummy,                           dummy, dummy, dummy, dummy, dummy, dummy);}int pcan_hw_getSNR(struct pcandev *dev, u32 *pdwSNR){  int err = 0;  ULCONV SNR;  u8  dummy;  int i = 1;    DPRINTK(KERN_DEBUG "%s: pcan_hw_getSNR()\n", DEVICE_NAME);   memset(&SNR, 0, sizeof(SNR));    // sometimes the hardware won't provide the number - so try twice  do    err = pcan_hw_getcontrol_urb(dev, 6, 1, &SNR.uc[3], &SNR.uc[2], &SNR.uc[1], &SNR.uc[0], &dummy, &dummy, &dummy, &dummy);  while ((i--) && (err == -2));    *pdwSNR = SNR.ul;    DPRINTK(KERN_DEBUG "%s: SNR = 0x%08x\n", DEVICE_NAME, *pdwSNR);  return err;}//****************************************************************************// init hardware partsint pcan_hw_Init(struct pcandev *dev, u16 btr0btr1, u8 bListenOnly){  int err = 0;  DPRINTK(KERN_DEBUG "%s: pcan_hw_Init()\n", DEVICE_NAME);   err = pcan_hw_setBTR0BTR1(dev, btr0btr1);  if (err)    goto fail;  if (dev->port.usb.ucRevision > 3)  {    // set listen only    if (bListenOnly)      err = pcan_hw_SetCANSilentOn(dev);    else      err = pcan_hw_SetCANSilentOff(dev);    if (err)      goto fail;  }  else  {    // generate err if one tries to set bListenOnly    if (bListenOnly)    {      err = -EINVAL;      goto fail;    }  }  // don't know how to handle - walk the save way  err = pcan_hw_SetExtVCCOff(dev);    // prepare for new start of timestamp calculation  pcan_reset_timestamp(dev);  fail:  return err;}//****************************************************************************// takes USB-message frames out of ucMsgPtr, decodes and packs them into readFifoint pcan_hw_DecodeMessage(struct pcandev *dev, u8 *ucMsgPtr, int lCurrentLength){  int err = 0;  int i, j;  u8 ucMsgPrefix;  u8 ucMsgLen;         // number of frames in one USB packet  u8 ucStatusLen = 0;  // storage for the status/length entry leading each data frame  u8 ucLen;            // len in bytes of received (CAN) data  UWCONV       wTimeStamp;  u8           *ucMsgStart = ucMsgPtr; // store start of buffer for overflow compare  int rwakeup = 0;  u8  *org = ucMsgPtr;  u8  dataPacketCounter = 0;  //DPRINTK(KERN_DEBUG "%s: pcan_hw_DecodeMessage(%p, %d)\n", DEVICE_NAME, ucMsgPtr, lCurrentLength);   // sometimes is nothing to do  if (!lCurrentLength)    return err;    // get prefix of message and step over  ucMsgPrefix = *ucMsgPtr++;  // get length of message and step over  ucMsgLen    = *ucMsgPtr++;  for (i = 0; (i < ucMsgLen); i++)  {    ULCONV localID;    struct timeval tv;    ucStatusLen = *ucMsgPtr++;    // TODO: take timestamp from PCAN-USB    do_gettimeofday(&tv);          // normal CAN message are always with timestamp    if (!(ucStatusLen & STLN_INTERNAL_DATA))    {      int nRtrFrame;      struct can_frame frame;                  ucLen = ucStatusLen & STLN_DATA_LENGTH;      if (ucLen > 8)        ucLen = 8;      frame.can_dlc = ucLen;            nRtrFrame = ucStatusLen & STLN_RTR;      if (nRtrFrame)        frame.can_id = CAN_RTR_FLAG;         // re-set to RTR value      else        frame.can_id = 0;                    // re-set to default value              if (ucStatusLen & STLN_EXTENDED_ID)      {        frame.can_id |= CAN_EFF_FLAG; // modify if it was extended                #if defined(__LITTLE_ENDIAN)        localID.uc[0] = *ucMsgPtr++;        localID.uc[1] = *ucMsgPtr++;        localID.uc[2] = *ucMsgPtr++;        localID.uc[3] = *ucMsgPtr++;        #elif defined(__BIG_ENDIAN)        localID.uc[3] = *ucMsgPtr++;        localID.uc[2] = *ucMsgPtr++;        localID.uc[1] = *ucMsgPtr++;        localID.uc[0] = *ucMsgPtr++;        #else          #error  "Please fix the endianness defines in <asm/byteorder.h>"        #endif          localID.ul   >>= 3;      }      else      {        localID.ul    = 0;        #if defined(__LITTLE_ENDIAN)        localID.uc[0] = *ucMsgPtr++;        localID.uc[1] = *ucMsgPtr++;        #elif defined(__BIG_ENDIAN)        localID.uc[3] = *ucMsgPtr++;        localID.uc[2] = *ucMsgPtr++;        #else          #error  "Please fix the endianness defines in <asm/byteorder.h>"        #endif          localID.ul   >>= 5;      }      frame.can_id |= localID.ul;      // read timestamp, first timestamp in packet is 16 bit AND data, following timestamps are 8 bit in length      if (!dataPacketCounter)      {        #if defined(__LITTLE_ENDIAN)        wTimeStamp.uc[0] = *ucMsgPtr++;        wTimeStamp.uc[1] = *ucMsgPtr++;        #elif defined(__BIG_ENDIAN)        wTimeStamp.uc[1] = *ucMsgPtr++;        wTimeStamp.uc[0] = *ucMsgPtr++;        #else          #error  "Please fix the endianness defines in <asm/byteorder.h>"        #endif                pcan_updateTimeStampFromWord(dev, wTimeStamp.uw, i);      }      else        pcan_updateTimeStampFromByte(dev, *ucMsgPtr++);      // read data      j = 0;      if (!nRtrFrame)      {        while (ucLen--)          frame.data[j++] = *ucMsgPtr++;      }      // only for beauty, replace useless telegram content with zeros      while (j < 8)        frame.data[j++] = 0;            if ((err = pcan_xxxdev_rx(dev, &frame, &tv)) < 0) // put into data sink        goto fail;               if (err > 0) // successfully enqueued into chardev FIFO        rwakeup++;      dataPacketCounter++;    }    // Status Daten    else    {      u8 ucFunction;      u8 ucNumber;      u8 dummy;      TPCANRdMsg msg;      struct can_frame ef; /* error frame */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -