All of lore.kernel.org
 help / color / mirror / Atom feed
* New USB driver, looking for advice
@ 2020-12-07  2:57 Christian Gagneraud
  2020-12-08 14:59 ` Marc Kleine-Budde
  0 siblings, 1 reply; 8+ messages in thread
From: Christian Gagneraud @ 2020-12-07  2:57 UTC (permalink / raw)
  To: linux-can

Hi all,

I'm looking at creating a new CAN driver for a USB device [1].
This device has a custom protocol over bulk endpoints.
I was able to create a simple driver, based on usb-skeleton.c that
allows to speak this protocol by opening a custom har device.
I've been looking at the current implementation in [2], I think my
device is a bit special, you cannot read CAN frames w/o sending a
'read' command, so i need some sort of polling.
AFAIK, the Linux USB stack provides that for me, except that the
device won't read anything unless you send it a command.
I have the feeling that current drivers are for devices that can
return data by just scheduling read transfer.
Anyone would have a clue on how these drivers work, and if my device
is really that special?

Any hint, point out or reading pointers are much appreciated.

Thanks,
Chris

PS: This is for marine applications, NMEA2000 which uses CAN HW and is
wire-compatible with J1939

[1] https://www.simrad-yachting.com/simrad/type/accessories/cables-connectors/navico-can-to-usb-converter-st10/
[2] https://github.com/torvalds/linux/tree/master/drivers/net/can/usb

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: New USB driver, looking for advice
  2020-12-07  2:57 New USB driver, looking for advice Christian Gagneraud
@ 2020-12-08 14:59 ` Marc Kleine-Budde
  2020-12-09 11:03   ` Marc Kleine-Budde
  2020-12-09 20:24   ` Christian Gagneraud
  0 siblings, 2 replies; 8+ messages in thread
From: Marc Kleine-Budde @ 2020-12-08 14:59 UTC (permalink / raw)
  To: Christian Gagneraud, linux-can


[-- Attachment #1.1: Type: text/plain, Size: 1554 bytes --]

On 12/7/20 3:57 AM, Christian Gagneraud wrote:
> I'm looking at creating a new CAN driver for a USB device [1]. This device
> has a custom protocol over bulk endpoints. I was able to create a simple
> driver, based on usb-skeleton.c that allows to speak this protocol by opening
> a custom har device.

Do you already have code available somewhere?

> I've been looking at the current implementation in [2], I think my device is
> a bit special, you cannot read CAN frames w/o sending a 'read' command, so i
> need some sort of polling. AFAIK, the Linux USB stack provides that for me,
> except that the device won't read anything unless you send it a command.

I don't know if you have to implement the polling yourself or if there is a
polling helper. I'll ask my co-workers.

Is that a Interrupt Transfer Endpoint or a normal Bulk Endpoint?

> I have the feeling that current drivers are for devices that can
> return data by just scheduling read transfer.

Yes. Current drivers get notified by the device, if there is a CAN frame waiting.

> Anyone would have a clue on how these drivers work, and if my device
> is really that special?

Yes, your device is quite special :)

> Any hint, point out or reading pointers are much appreciated.

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: New USB driver, looking for advice
  2020-12-08 14:59 ` Marc Kleine-Budde
@ 2020-12-09 11:03   ` Marc Kleine-Budde
  2020-12-09 20:24   ` Christian Gagneraud
  1 sibling, 0 replies; 8+ messages in thread
From: Marc Kleine-Budde @ 2020-12-09 11:03 UTC (permalink / raw)
  To: Christian Gagneraud, linux-can


[-- Attachment #1.1: Type: text/plain, Size: 581 bytes --]

On 12/8/20 3:59 PM, Marc Kleine-Budde wrote:
> I don't know if you have to implement the polling yourself or if there is a
> polling helper. I'll ask my co-workers.
> 
> Is that a Interrupt Transfer Endpoint or a normal Bulk Endpoint?

Can you give us the output of "sudo lsusb -v"?

regards,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: New USB driver, looking for advice
  2020-12-08 14:59 ` Marc Kleine-Budde
  2020-12-09 11:03   ` Marc Kleine-Budde
@ 2020-12-09 20:24   ` Christian Gagneraud
  2020-12-10  7:36     ` Marc Kleine-Budde
  1 sibling, 1 reply; 8+ messages in thread
From: Christian Gagneraud @ 2020-12-09 20:24 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: linux-can

On Wed, 9 Dec 2020 at 03:59, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
>
> On 12/7/20 3:57 AM, Christian Gagneraud wrote:
> > I'm looking at creating a new CAN driver for a USB device [1]. This device
> > has a custom protocol over bulk endpoints. I was able to create a simple
> > driver, based on usb-skeleton.c that allows to speak this protocol by opening
> > a custom har device.
>
> Do you already have code available somewhere?

No, not yet. This driver is really a slightly modified usb-skeleton
where you read/write bulk packets one by one on a char device.
I have as well a python version that was used as a proof of concept
(using pyusb).

>
> > I've been looking at the current implementation in [2], I think my device is
> > a bit special, you cannot read CAN frames w/o sending a 'read' command, so i
> > need some sort of polling. AFAIK, the Linux USB stack provides that for me,
> > except that the device won't read anything unless you send it a command.
>
> I don't know if you have to implement the polling yourself or if there is a
> polling helper. I'll ask my co-workers.
>
> Is that a Interrupt Transfer Endpoint or a normal Bulk Endpoint?

AFAIU the firmware, it's just a normal Bulk Endpoint, which i think is
the problem.

> > I have the feeling that current drivers are for devices that can
> > return data by just scheduling read transfer.
>
> Yes. Current drivers get notified by the device, if there is a CAN frame waiting.
>
> > Anyone would have a clue on how these drivers work, and if my device
> > is really that special?
>
> Yes, your device is quite special :)

Hum, no good news...

The device has 3 interfaces:
- keyboard
- mouse
- device specific (CAN)

The reason for HID is that these sort of devices[1] communicate over N2K
[1] https://www.simrad-yachting.com/en-nz/simrad/type/autopilots/autopilot-remote-controllers/simrad-op50-remote/

Thanks,
Chris

$ lsusb -v
Bus 001 Device 105: ID 1cda:03e8
Device Descriptor:
 bLength                18
 bDescriptorType         1
 bcdUSB               2.00
 bDeviceClass            0 (Defined at Interface level)
 bDeviceSubClass         0
 bDeviceProtocol         0
 bMaxPacketSize0        64
 idVendor           0x1cda
 idProduct          0x03e8
 bcdDevice            0.13
 iManufacturer           1 Navico Asia Pacific Ltd
 iProduct                2 Navico USB IO Computer
 iSerial                 3 SN-03EC-FFFFFFFF
 bNumConfigurations      1
 Configuration Descriptor:
   bLength                 9
   bDescriptorType         2
   wTotalLength           82
   bNumInterfaces          3
   bConfigurationValue     1
   iConfiguration          0
   bmAttributes         0x80
     (Bus Powered)
   MaxPower              100mA
   Interface Descriptor:
     bLength                 9
     bDescriptorType         4
     bInterfaceNumber        0
     bAlternateSetting       0
     bNumEndpoints           1
     bInterfaceClass         3 Human Interface Device
     bInterfaceSubClass      1 Boot Interface Subclass
     bInterfaceProtocol      1 Keyboard
     iInterface              4 Virtual Keyboard
       HID Device Descriptor:
         bLength                 9
         bDescriptorType        33
         bcdHID               1.01
         bCountryCode            0 Not supported
         bNumDescriptors         1
         bDescriptorType        34 Report
         wDescriptorLength      63
        Report Descriptors:
          ** UNAVAILABLE **
     Endpoint Descriptor:
       bLength                 7
       bDescriptorType         5
       bEndpointAddress     0x81  EP 1 IN
       bmAttributes            3
         Transfer Type            Interrupt
         Synch Type               None
         Usage Type               Data
       wMaxPacketSize     0x0008  1x 8 bytes
       bInterval              10
   Interface Descriptor:
     bLength                 9
     bDescriptorType         4
     bInterfaceNumber        1
     bAlternateSetting       0
     bNumEndpoints           1
     bInterfaceClass         3 Human Interface Device
     bInterfaceSubClass      1 Boot Interface Subclass
     bInterfaceProtocol      2 Mouse
     iInterface              5 Virtual Mouse
       HID Device Descriptor:
         bLength                 9
         bDescriptorType        33
         bcdHID               1.01
         bCountryCode            0 Not supported
         bNumDescriptors         1
         bDescriptorType        34 Report
         wDescriptorLength      50
        Report Descriptors:
          ** UNAVAILABLE **
     Endpoint Descriptor:
       bLength                 7
       bDescriptorType         5
       bEndpointAddress     0x84  EP 4 IN
       bmAttributes            3
         Transfer Type            Interrupt
         Synch Type               None
         Usage Type               Data
       wMaxPacketSize     0x0008  1x 8 bytes
       bInterval              10
   Interface Descriptor:
     bLength                 9
     bDescriptorType         4
     bInterfaceNumber        2
     bAlternateSetting       0
     bNumEndpoints           2
     bInterfaceClass       255 Vendor Specific Class
     bInterfaceSubClass    255 Vendor Specific Subclass
     bInterfaceProtocol    255 Vendor Specific Protocol
     iInterface              6 Client Application Interface
     Endpoint Descriptor:
       bLength                 7
       bDescriptorType         5
       bEndpointAddress     0x82  EP 2 IN
       bmAttributes            2
         Transfer Type            Bulk
         Synch Type               None
         Usage Type               Data
       wMaxPacketSize     0x0040  1x 64 bytes
       bInterval               0
     Endpoint Descriptor:
       bLength                 7
       bDescriptorType         5
       bEndpointAddress     0x02  EP 2 OUT
       bmAttributes            2
         Transfer Type            Bulk
         Synch Type               None
         Usage Type               Data
       wMaxPacketSize     0x0040  1x 64 bytes
       bInterval               0
Device Status:     0x0000
 (Bus Powered)

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: New USB driver, looking for advice
  2020-12-09 20:24   ` Christian Gagneraud
@ 2020-12-10  7:36     ` Marc Kleine-Budde
  2020-12-10 22:26       ` Christian Gagneraud
  0 siblings, 1 reply; 8+ messages in thread
From: Marc Kleine-Budde @ 2020-12-10  7:36 UTC (permalink / raw)
  To: Christian Gagneraud; +Cc: linux-can


[-- Attachment #1.1: Type: text/plain, Size: 1539 bytes --]

On 12/9/20 9:24 PM, Christian Gagneraud wrote:
>> I don't know if you have to implement the polling yourself or if there is a
>> polling helper. I'll ask my co-workers.
>>
>> Is that a Interrupt Transfer Endpoint or a normal Bulk Endpoint?
> 
> AFAIU the firmware, it's just a normal Bulk Endpoint, which i think is
> the problem.

Yes, with an Interrupt Endpoint things would be easier.

>>> I have the feeling that current drivers are for devices that can
>>> return data by just scheduling read transfer.
>>
>> Yes. Current drivers get notified by the device, if there is a CAN frame waiting.
>>
>>> Anyone would have a clue on how these drivers work, and if my device
>>> is really that special?
>>
>> Yes, your device is quite special :)
> 
> Hum, no good news...
> 
> The device has 3 interfaces:
> - keyboard
> - mouse
> - device specific (CAN)

I think you have to implement the polling yourself. Start a transfer on
ndo_open(). In the completion handler handle the received data. In case you have
recieved a CAN frame, submit a new transfer in case you haven't received data
yet, schedule delayed work with a delay, e.g. 1ms. Once you have that running
you have fine tune the number of running transfers and delays.

Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: New USB driver, looking for advice
  2020-12-10  7:36     ` Marc Kleine-Budde
@ 2020-12-10 22:26       ` Christian Gagneraud
  2020-12-11  8:39         ` Marc Kleine-Budde
  0 siblings, 1 reply; 8+ messages in thread
From: Christian Gagneraud @ 2020-12-10 22:26 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: linux-can

On Thu, 10 Dec 2020 at 20:36, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
> >>> I have the feeling that current drivers are for devices that can
> >>> return data by just scheduling read transfer.
> >>
> >> Yes. Current drivers get notified by the device, if there is a CAN frame waiting.
> >>
> >>> Anyone would have a clue on how these drivers work, and if my device
> >>> is really that special?
> >>
> >> Yes, your device is quite special :)
> >
> > Hum, no good news...
> >
> > The device has 3 interfaces:
> > - keyboard
> > - mouse
> > - device specific (CAN)
>
> I think you have to implement the polling yourself. Start a transfer on
> ndo_open(). In the completion handler handle the received data. In case you have
> recieved a CAN frame, submit a new transfer in case you haven't received data
> yet, schedule delayed work with a delay, e.g. 1ms. Once you have that running
> you have fine tune the number of running transfers and delays.

Thanks Marc for the hints.
I'll look into that, this will certainly take time, I'm not in a rush.
Full disclosure: I am actually an employee of Navico (the manufacturer
of the device), I'm currently waiting for approval to publish code
related to that device. This shouldn't be an issue, I just need the
administrative work done.

Chris

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: New USB driver, looking for advice
  2020-12-10 22:26       ` Christian Gagneraud
@ 2020-12-11  8:39         ` Marc Kleine-Budde
  2021-02-18  2:14           ` Christian Gagneraud
  0 siblings, 1 reply; 8+ messages in thread
From: Marc Kleine-Budde @ 2020-12-11  8:39 UTC (permalink / raw)
  To: Christian Gagneraud; +Cc: linux-can


[-- Attachment #1.1: Type: text/plain, Size: 1414 bytes --]

On 12/10/20 11:26 PM, Christian Gagneraud wrote:
>>>> Yes, your device is quite special :)

[...]

>> I think you have to implement the polling yourself. Start a transfer on
>> ndo_open(). In the completion handler handle the received data. In case you have
>> recieved a CAN frame, submit a new transfer in case you haven't received data
>> yet, schedule delayed work with a delay, e.g. 1ms. Once you have that running
>> you have fine tune the number of running transfers and delays.
> 
> Thanks Marc for the hints.
> I'll look into that, this will certainly take time, I'm not in a rush.
> Full disclosure: I am actually an employee of Navico (the manufacturer
> of the device),

Nice! There are several CAN devices which have mainline Linux spport by their
manufacturers. Is there any driver for other operating systems like Windows,
etc? You might talk to the developers to find out, how they solve the problem of
polling.

> I'm currently waiting for approval to publish code
> related to that device. This shouldn't be an issue, I just need the
> administrative work done.

Fingers crossed!

regard,
Marc

-- 
Pengutronix e.K.                 | Marc Kleine-Budde           |
Embedded Linux                   | https://www.pengutronix.de  |
Vertretung West/Dortmund         | Phone: +49-231-2826-924     |
Amtsgericht Hildesheim, HRA 2686 | Fax:   +49-5121-206917-5555 |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: New USB driver, looking for advice
  2020-12-11  8:39         ` Marc Kleine-Budde
@ 2021-02-18  2:14           ` Christian Gagneraud
  0 siblings, 0 replies; 8+ messages in thread
From: Christian Gagneraud @ 2021-02-18  2:14 UTC (permalink / raw)
  To: Marc Kleine-Budde; +Cc: linux-can

On Fri, 11 Dec 2020 at 21:39, Marc Kleine-Budde <mkl@pengutronix.de> wrote:
>
> On 12/10/20 11:26 PM, Christian Gagneraud wrote:
> >>>> Yes, your device is quite special :)
>
> [...]
>
> >> I think you have to implement the polling yourself. Start a transfer on
> >> ndo_open(). In the completion handler handle the received data. In case you have
> >> recieved a CAN frame, submit a new transfer in case you haven't received data
> >> yet, schedule delayed work with a delay, e.g. 1ms. Once you have that running
> >> you have fine tune the number of running transfers and delays.
> >
> > Thanks Marc for the hints.
> > I'll look into that, this will certainly take time, I'm not in a rush.
> > Full disclosure: I am actually an employee of Navico (the manufacturer
> > of the device),
>
> Nice! There are several CAN devices which have mainline Linux spport by their
> manufacturers. Is there any driver for other operating systems like Windows,
> etc? You might talk to the developers to find out, how they solve the problem of
> polling.
>
> > I'm currently waiting for approval to publish code
> > related to that device. This shouldn't be an issue, I just need the
> > administrative work done.
>
> Fingers crossed!

I have 3 code base to share:

1. https://github.com/NavicoOS/pegasus-python-can/blob/main/python-can-pegasus/pegasus_iface.py
This code show how to talk to the USB device, it is quite compact and simple
The workhorse are_usb_bulk(), _write_usb_packet() and _read_usb_packet()
There are different types of packet, with a straight mapping with
open, close, bus on, bus off, read, write, ...

2. https://github.com/NavicoOS/pegasus-linux-can/tree/main/pegasus_usb
This is a simple char device driver on top of the Linux USB stack
You can manually write command, and read answer to/from this device,
the README [1], show how to handle the '
get_descriptor' and compare the binary answer with what the above
python based project

3. https://github.com/NavicoOS/pegasus-linux-can/tree/main/pegasus_can
I thought i had an initial PoC based on some linux-can driver, but
obviously not, this is the same as above, so let's ignore it for now,
unless i find a more up to date source tree.

[1] https://github.com/NavicoOS/pegasus-linux-can/blob/main/README.md

Chris

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-02-18  2:15 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-12-07  2:57 New USB driver, looking for advice Christian Gagneraud
2020-12-08 14:59 ` Marc Kleine-Budde
2020-12-09 11:03   ` Marc Kleine-Budde
2020-12-09 20:24   ` Christian Gagneraud
2020-12-10  7:36     ` Marc Kleine-Budde
2020-12-10 22:26       ` Christian Gagneraud
2020-12-11  8:39         ` Marc Kleine-Budde
2021-02-18  2:14           ` Christian Gagneraud

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.