]> rtime.felk.cvut.cz Git - lincan.git/blobdiff - lincan/src/usbcan.c
Added vendor functions to embedded application, data transferred by usb channel seria...
[lincan.git] / lincan / src / usbcan.c
index cb1c9b0b2d285433fefec52715c629ca03ccdf5f..a18f8621cda002f65ace1943d966577e9c257cef 100644 (file)
@@ -5,7 +5,6 @@
  * Version lincan-0.3  17 Jul 2008
  */
 
-#include "../include/kthread.h"
 #include "../include/can.h"
 #include "../include/can_sysdep.h"
 #include "../include/main.h"
 #include "../include/setup.h"
 #include "../include/usbcan.h"
 
+static int usbcan_probe(struct usb_interface *interface, const struct usb_device_id *id);
+static void usbcan_disconnect(struct usb_interface *interface);
+
+/* table of devices that work with this driver */
+static struct usb_device_id usbcan_table [] = {
+       { USB_DEVICE(USBCAN_VENDOR_ID, USBCAN_PRODUCT_ID) },
+       { }                                     /* Terminating entry */
+};
+MODULE_DEVICE_TABLE(usb, usbcan_table);
+
+static struct usb_driver usbcan_driver = {
+       .name =         "usbcan",
+       .id_table = usbcan_table,
+       .probe =        usbcan_probe,
+       .disconnect =   usbcan_disconnect,
+};
+
 /**
  * usbcan_request_io: - reserve io or memory range for can board
  * @candev: pointer to candevice/board which asks for io. Field @io_addr
@@ -253,17 +269,17 @@ int usbcan_extended_mask(struct canchip_t *chip, unsigned long code, unsigned  l
        int retval;
        struct usbcan_usb *dev=(struct usbcan_usb*)chip->hostdevice->sysdevptr.anydev;
 
-       struct usbcan_mask_t mask={
-               .code=code;
-               .mask=mask;
-       };
+       __u8 usbbuf[16];
+
+       *(uint32_t *)(usbbuf)=cpu_to_le32(mask);
+       *(uint32_t *)(usbbuf+4)=cpu_to_le32(code);
 
        retval=usb_control_msg(dev->udev,
                usb_sndctrlpipe(dev->udev, dev->ctl_out_endpointAddr),
                USBCAN_VENDOR_EXT_MASK_SET,
                USB_TYPE_VENDOR,
                0, chip->chip_idx,
-               &mask, sizeof(usbcan_mask_t),
+               &usbbuf, 16,
                10000);
        if (retval<0)
                return -ENODEV;
@@ -273,11 +289,11 @@ int usbcan_extended_mask(struct canchip_t *chip, unsigned long code, unsigned  l
                USBCAN_VENDOR_EXT_MASK_STATUS,
                USB_TYPE_VENDOR,
                0, chip->chip_idx,
-               dev->ctl_in_buffer, dev->ctl_in_size,
+               &usbbuf, 16,
                10000);
 
-       if (retval==1){
-               if(dev->ctl_in_buffer[0]==1){
+       if (retval==16){
+               if(usbbuf[0]==1){
                        DEBUGMSG("Setting acceptance code to 0x%lx\n",(unsigned long)code);
                        DEBUGMSG("Setting acceptance mask to 0x%lx\n",(unsigned long)mask);
                        return 0;
@@ -306,21 +322,19 @@ int usbcan_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
        int retval;
        struct usbcan_usb *dev=(struct usbcan_usb*)chip->hostdevice->sysdevptr.anydev;
 
-       // Data too big to use single receive control message
-       struct can_baudparams_t baud={
-               .flags=flags,
-               .baudrate=rate,
-               .sjw=sjw,
-               .sample_pt=sampl_pt,
-       };
+       __u8 usbbuf[16];
 
+       *(int32_t *)(usbbuf)=cpu_to_le32(rate);
+       *(int32_t *)(usbbuf+4)=cpu_to_le32(sjw);
+       *(int32_t *)(usbbuf+8)=cpu_to_le32(sampl_pt);
+       *(int32_t *)(usbbuf+12)=cpu_to_le32(flags);
 
        retval=usb_control_msg(dev->udev,
                usb_sndctrlpipe(dev->udev, dev->ctl_out_endpointAddr),
                USBCAN_VENDOR_BAUD_RATE_SET,
                USB_TYPE_VENDOR,
                0, chip->chip_idx,
-               &baud, sizeof(can_baudparams_t),
+               &usbbuf, 16,
                10000);
        if (retval<0)
                return -ENODEV;
@@ -330,11 +344,11 @@ int usbcan_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw,
                USBCAN_VENDOR_BAUD_RATE_STATUS,
                USB_TYPE_VENDOR,
                0, chip->chip_idx,
-               dev->ctl_in_buffer, dev->ctl_in_size,
+               usbbuf, 16,
                10000);
 
-       if (retval==1){
-               if(dev->ctl_in_buffer[0]==1)
+       if (retval==16){
+               if(usbbuf[0]==1)
                        return 0;
        }
 
@@ -377,6 +391,7 @@ int usbcan_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
        struct usbcan_usb *dev=(struct usbcan_usb*)chip->hostdevice->sysdevptr.anydev;
        int i=0;
        int len;
+       __u8 *ptr;
 
        /* Wait until Transmit Buffer Status is released */
        while ( usbcan_chip_queue_status(chip) &&
@@ -388,29 +403,20 @@ int usbcan_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj,
                return -EIO;
        }
 
-       dev->tx_msg.chip_id=(__u8)chip->chip_idx;
+       *(uint8_t *)(dev->tx_msg)=chip->chip_idx & 0xFF;
 
        len = msg->length;
        if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
-       dev->tx_msg.length=(__u8)len;
-       dev->tx_msg.flags=(__u16)msg->flags;
-
-       if(msg->flags&MSG_EXT) {
-               dev->tx_msg.id[0]=(msg->id) & 0xff;
-               dev->tx_msg.id[1]=(msg->id>>8) & 0xff;
-               dev->tx_msg.id[2]=(msg->id>>16) & 0xff;
-               dev->tx_msg.id[3]=(msg->id>>24) & 0xff;
-       } else {
-               dev->tx_msg.id[0]=(msg->id) & 0xff;
-               dev->tx_msg.id[1]=(msg->id>>8) & 0xff;
-               dev->tx_msg.id[2]=0;
-               dev->tx_msg.id[3]=0;
-       }
-       for(i=0; i < len; i++) {
-               dev->tx_msg.data[i]=(__u8) msg->data[i];
+
+       *(uint8_t *)(dev->tx_msg+1)=len & 0xFF;
+       *(uint16_t *)(dev->tx_msg+2)=cpu_to_le16(msg->flags);
+       *(uint32_t *)(dev->tx_msg+4)=cpu_to_le32(msg->id);
+
+       for(ptr=dev->tx_msg+8,i=0; i < len; ptr++,i++) {
+               *ptr=msg->data[i] & 0xFF;
        }
-       for(i; i < 8; i++) {
-               dev->tx_msg.data[i]=0;
+       for(; i < 8; ptr++,i++) {
+               *ptr=0;
        }
        return 0;
 }
@@ -430,12 +436,12 @@ int usbcan_send_msg(struct canchip_t *chip, struct msgobj_t *obj,
                                                        struct canmsg_t *msg)
 {
        struct usbcan_usb *dev=(struct usbcan_usb*)chip->hostdevice->sysdevptr.anydev;
-       int len;
+       int len,retval;
 
        set_bit(USBCAN_TX_PENDING,&dev->flags);
        retval=usb_bulk_msg(dev->udev,
                        usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
-                       &dev->tx_msg, sizeof(usbcan_canmsg_t),
+                       &dev->tx_msg, 16,
                        &len,10000);
        clear_bit(USBCAN_TX_PENDING,&dev->flags);
        if (retval){
@@ -480,12 +486,13 @@ int usbcan_set_btregs(struct canchip_t *chip, unsigned short btr0,
 {
        int retval;
        struct usbcan_usb *dev=(struct usbcan_usb*)chip->hostdevice->sysdevptr.anydev;
+       uint16_t value=(btr1&0xFF)<<8 | (btr0&0xFF);
 
        retval = usb_control_msg(dev->udev,
        usb_rcvctrlpipe(dev->udev, dev->ctl_in_endpointAddr),
        USBCAN_VENDOR_SET_BTREGS,
        USB_TYPE_VENDOR,
-       btr1<<8 | btr0, chip->chip_idx,
+       cpu_to_le16(value), chip->chip_idx,
        dev->ctl_in_buffer, dev->ctl_in_size,
        10000);
 
@@ -547,9 +554,9 @@ int usbcan_chip_queue_status(struct canchip_t *chip)
 
        if (retval==1){
                if(dev->ctl_in_buffer[0]==1)
-                       return 1;
-               if(dev->ctl_in_buffer[0]==0)
                        return 0;
+               if(dev->ctl_in_buffer[0]==0)
+                       return 1;
        }
        return -ENODEV;
 }
@@ -1003,7 +1010,7 @@ void usbcan_read_kthread(kthread_t *kthread)
        dev->rcv->dev = dev->udev;
        usb_fill_bulk_urb(dev->rcv, dev->udev,
                         usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),
-                        &dev->rcv_msg, sizeof(usbcan_canmsg_t),
+                        &dev->rcv_msg, 16,
                         usbcan_rcv, dev);
 
   /* an endless loop in which we are doing our work */
@@ -1016,9 +1023,9 @@ void usbcan_read_kthread(kthread_t *kthread)
                }
                /* fall asleep */
                wait_event_interruptible(kthread->queue,
-                       test_bit(USBCAN_CHIP_DATA_READ,&chip_data->flags)
-                       || test_bit(USBCAN_CHIP_TERMINATE,&chip_data->flags)
-                       || test_bit(USBCAN_CHIP_ERROR,&chip_data->flags)
+                       test_bit(USBCAN_DATA_READ,&dev->flags)
+                       || test_bit(USBCAN_TERMINATE,&dev->flags)
+                       || test_bit(USBCAN_ERROR,&dev->flags)
                );
 
                /* We need to do a memory barrier here to be sure that
@@ -1032,37 +1039,32 @@ void usbcan_read_kthread(kthread_t *kthread)
                        break;
                }
 
-               if (test_bit(USBCAN_CHIP_ERROR,&chip_data->flags)){
+               if (test_bit(USBCAN_ERROR,&dev->flags)){
                        CANMSG("URB error %d\n",retval);
                        break;
                }
 
                { /* Normal work to do */
-                       if (test_bit(USBCAN_CHIP_DATA_READ,&chip_data->flags)){
+                       if (test_bit(USBCAN_DATA_READ,&dev->flags)){
                                int i, len;
-                               clear_bit(USBCAN_CHIP_DATA_READ,&chip_data->flags);
-
-                               if ((dev->candev->chip[dev->rcv_msg.chip_id])&&
-                                       (dev->candev->chip[dev->rcv_msg.chip_id].flags & CHIP_CONFIGURED)){
-
-                                       obj=dev->candev->chip[dev->rcv_msg.chip_id]->msgobj[0];
-                                       if (dev->rcv_msg.flags & MSG_EXT) {
-                                               obj->rx_msg.id =
-                                                       (dev->rcv_msg.id[0]) +
-                                                       (dev->rcv_msg.id[1]<<8) +
-                                                       (dev->rcv_msg.id[2]<<16) +
-                                                       (dev->rcv_msg.id[3]<<24);
-                                       } else {
-                                               obj->rx_msg.id =
-                                                       (dev->rcv_msg.id[0]) +
-                                                       (dev->rcv_msg.id[1]<<8);
-                                       }
-                                       obj->rx_msg.flags = dev->rcv_msg.flags;
-                                       len=dev->rcv_msg.length;
+                               clear_bit(USBCAN_DATA_READ,&dev->flags);
+
+                               if ((dev->candev->chip[dev->rcv_msg[0]])&&
+                                       (dev->candev->chip[dev->rcv_msg[0]]->flags & CHIP_CONFIGURED)
+                               ){
+                                       __u8 *ptr;
+
+                                       obj=dev->candev->chip[dev->rcv_msg[0]]->msgobj[0];
+
+                                       len=*(uint8_t *)(dev->rcv_msg+1);
                                        if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH;
                                        obj->rx_msg.length = len;
-                                       for(i=0; i< len; i++) {
-                                               obj->rx_msg.data[i]=obj->rx_msg.data[i];
+
+                                       obj->rx_msg.flags=le16_to_cpu(*(uint16_t *)(dev->rcv_msg+2));
+                                       obj->rx_msg.id=le32_to_cpu((*(uint32_t *)(dev->rcv_msg+4)));
+
+                                       for(ptr=dev->rcv_msg+8,i=0; i < len; ptr++,i++) {
+                                               obj->rx_msg.data[i]=*ptr;
                                        }
 
                                        // fill CAN message timestamp