CP2102 driver

Anything related to hardware, devices, drivers and how to use them with Ultibo.
User avatar
Rassamaha78
Posts: 52
Joined: Wed Dec 20, 2017 1:09 am
Location: Russia

CP2102 driver

Postby Rassamaha78 » Sat Mar 30, 2019 1:01 pm

In my project I want to use RFID Reader SL500. It is based on a USB to UART Bridge chip - CP2102 from Silicon Labs (VID 10C4, PID EA60). Is it possible to work with this chip from Ultibo ?

P.S. Ultibo supports working with the FTDI Serial driver, i found Linux driver for CP210x ( linux/drivers/usb/serial/cp210x.c ), is it possible to remake it to work with CP2102 ?
User avatar
Ultibo
Site Admin
Posts: 2207
Joined: Sat Dec 19, 2015 3:49 am
Location: Australia

Re: CP2102 driver

Postby Ultibo » Sun Mar 31, 2019 11:23 pm

Rassamaha78 wrote:In my project I want to use RFID Reader SL500. It is based on a USB to UART Bridge chip - CP2102 from Silicon Labs (VID 10C4, PID EA60). Is it possible to work with this chip from Ultibo ?

P.S. Ultibo supports working with the FTDI Serial driver, i found Linux driver for CP210x ( linux/drivers/usb/serial/cp210x.c ), is it possible to remake it to work with CP2102 ?

We don't have one of these devices but from a quick look at the Linux driver it doesn't look like there is anything unusual about it.

If you compare the Linux CP210x driver against the Linux PL2303 driver and the Ultibo PL2303 driver you can see a lot of similarities between them. The structure and overall design of an Ultibo driver for the CP210x would look very similar, the main differences would be in the device specific constants and requests.

How much of the work are you willing to tackle yourself? We can help with information and advice but right now we don't have much time available to work on porting the driver directly.
Ultibo.org | Make something amazing
https://ultibo.org
User avatar
Rassamaha78
Posts: 52
Joined: Wed Dec 20, 2017 1:09 am
Location: Russia

Re: CP2102 driver

Postby Rassamaha78 » Tue Apr 02, 2019 12:11 am

I will try to port the driver myself. I have a few questions:
1. How is the TPL2303SerialDevice record formed? As I understand it is different for each device, but I never found a description of this record.
2. Did I understand correctly that these functions are the same for all series of devices?

Code: Select all

 {CP210X Serial Functions}
 function CP210XSerialDeviceOpen( Serial: PSerialDevice; BaudRate, DataBits, StopBits, Parity, FlowControl, ReceiveDepth ,TransmitDepth: LongWord ): LongWord;
 function CP210XSerialDeviceClose( Serial: PSerialDevice ): LongWord;

 function CP210XSerialDeviceRead( Serial: PSerialDevice; Buffer: Pointer; Size, Flags: LongWord; var Count: LongWord ): LongWord;
 function CP210XSerialDeviceWrite( Serial: PSerialDevice; Buffer: Pointer; Size, Flags: LongWord; var Count: LongWord ): LongWord;

 {CP210X USB Functions}
 function CP210XDriverBind( Device: PUSBDevice; Interrface: PUSBInterface ): LongWord;
 function CP210XDriverUnbind( Device: PUSBDevice; Interrface: PUSBInterface ): LongWord;

 procedure CP210XReceiveWorker( Request: PUSBRequest );
 procedure CP210XReceiveComplete( Request: PUSBRequest );

 procedure CP210XTransmitStart( Request: PUSBRequest );
 procedure CP210XTransmitWorker( Request: PUSBRequest );
 procedure CP210XTransmitComplete( Request: PUSBRequest );

3. In the {CP210X Helper Functions} section, i need to implement functions designed specifically for this chip, that is:

Code: Select all

static void cp210x_get_termios(struct tty_struct *, struct usb_serial_port *);
static void cp210x_get_termios_port(struct usb_serial_port *port,
   tcflag_t *cflagp, unsigned int *baudp);
static void cp210x_change_speed(struct tty_struct *, struct usb_serial_port *,
                     struct ktermios *);
static void cp210x_set_termios(struct tty_struct *, struct usb_serial_port *,
                     struct ktermios*);
static bool cp210x_tx_empty(struct usb_serial_port *port);
static int cp210x_tiocmget(struct tty_struct *);
static int cp210x_tiocmset(struct tty_struct *, unsigned int, unsigned int);
static int cp210x_tiocmset_port(struct usb_serial_port *port,
      unsigned int, unsigned int);
static void cp210x_break_ctl(struct tty_struct *, int);
static int cp210x_attach(struct usb_serial *);
static void cp210x_disconnect(struct usb_serial *);
static void cp210x_release(struct usb_serial *);
static int cp210x_port_probe(struct usb_serial_port *);
static int cp210x_port_remove(struct usb_serial_port *);
static void cp210x_dtr_rts(struct usb_serial_port *p, int on);

4. Functions:

Code: Select all

 static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *);
 static void cp210x_close(struct usb_serial_port *);

are implemented in:

Code: Select all

  function CP210XSerialDeviceOpen( Serial: PSerialDevice; BaudRate, DataBits, StopBits, Parity, FlowControl, ReceiveDepth ,TransmitDepth: LongWord ): LongWord;
 function CP210XSerialDeviceClose( Serial: PSerialDevice ): LongWord;
User avatar
Ultibo
Site Admin
Posts: 2207
Joined: Sat Dec 19, 2015 3:49 am
Location: Australia

Re: CP2102 driver

Postby Ultibo » Tue Apr 02, 2019 7:22 am

Rassamaha78 wrote:1. How is the TPL2303SerialDevice record formed? As I understand it is different for each device, but I never found a description of this record.

The TPL2303SerialDevice record (or TCP210XSerialDevice in your case) is simply an extended version of the standard TSerialDevice which the Serial API expects to be passed to it for many functions and is used to keep track of the device.

If you look at its declaration in the PL2303 unit you will see that the very first field is a TSerialDevice like this:

Code: Select all

 TPL2303SerialDevice = record
  {Serial Properties}
  Serial:TSerialDevice;
  {USB Properties}
  ...

Because of the way FPC will reference the fields within the record we know the the Serial field will be at offset 0 and therefore we can typecast a PPL2303SerialDevice pointer to a PSerialDevice when required.

If you look at PL2303DriverBind() you can see that it allocates enough memory for a TPL2303SerialDevice when calling SerialDeviceCreateEx(), the additional fields can be anything your driver needs internally to keep track of the state, status and properties of the device which for a USB device will often be things like the endpoints and the transmit and receive requests.

Rassamaha78 wrote:2. Did I understand correctly that these functions are the same for all series of devices?

Yes that would be the minimum set of functions for a USB to Serial device, some devices like the PL2303 have an interrupt endpoint as well so they need a couple of extra functions but the CP210x doesn't seem to need that.

Rassamaha78 wrote:3. In the {CP210X Helper Functions} section, i need to implement functions designed specifically for this chip, that is:

You won't need to implement each of those directly, some will be part of standard functions above and others are very Linux specific.

For example cp210x_attach(), cp210x_disconnect() and cp210x_release() would be part of CP210XDriverBind() and CP210XDriverUnbind().

Some of the termio functions like cp210x_get_termios(), cp210x_get_termios_port(), cp210x_set_termios() and cp210x_tiocmget() are Linux specific and don't translate directly to Ultibo but they will show you how to get and set things like the baud rate, stop bits, control lines and modem status.

You will need to implement the vendor specific USB requests like cp210x_read_vendor_block() and cp210x_write_vendor_block() in order to configure the device registers.

Rassamaha78 wrote:4. Functions:

Code: Select all

 static int cp210x_open(struct tty_struct *tty, struct usb_serial_port *);
 static void cp210x_close(struct usb_serial_port *);

are implemented in:

Code: Select all

  function CP210XSerialDeviceOpen( Serial: PSerialDevice; BaudRate, DataBits, StopBits, Parity, FlowControl, ReceiveDepth ,TransmitDepth: LongWord ): LongWord;
 function CP210XSerialDeviceClose( Serial: PSerialDevice ): LongWord;

Yes that is correct, it won't be an exact 1:1 port of those functions to Ultibo but in general the set of operations will be very similar.

I would recommend starting with an outline unit based on the PL2303 and FTDI drivers with mostly empty versions of the standard functions from item 2 above, then port all of the register defines from the Linux driver such as the "Config request types" and "Config request codes" as well as the device ID table (see the PL2303 and FTDI drivers for the Ultibo format).

Once you have a rough outline start with the CP210XInit procedure which registers the driver and then the CP210XDriverBind function which the USB core will call when it has a new device to bind.

Add lots of logging to your driver and always do your early testing by plugging the device in after booting the Pi.

Let us know what more information we can provide.
Ultibo.org | Make something amazing
https://ultibo.org

Return to “General”

Who is online

Users browsing this forum: No registered users and 0 guests