From: Eli Cohen <echoline@gmail.com>
To: 9front@9front.org
Subject: new nusb/serial driver
Date: Thu, 11 Jun 2020 00:03:12 -0700 [thread overview]
Message-ID: <CAHwi9bz7qpA11VWd0r6nDdoseM_qiwR7rxwpdN8p5N74j0mO6g@mail.gmail.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 227 bytes --]
I have written an extremely limited and flaky CDC ACM driver for
nusb/serial. it works well enough to communicate with my Arduino Mega
2560. it would be nice if someone smarter than me with similar
hardware could look at this.
[-- Attachment #2: serial.patch --]
[-- Type: text/x-patch, Size: 1756 bytes --]
Only in /usr/glenda/nusb/serial: cdc.c
diff -ur /sys/src/cmd/nusb/serial/mkfile /usr/glenda/nusb/serial/mkfile
--- /sys/src/cmd/nusb/serial/mkfile Fri Dec 13 00:31:34 2019
+++ /usr/glenda/nusb/serial/mkfile Mon Jun 8 18:00:33 2020
@@ -1,7 +1,7 @@
</$objtype/mkfile
TARG=serial
-OFILES=ftdi.$O serial.$O prolific.$O ucons.$O silabs.$O ch340.$O
+OFILES=ftdi.$O serial.$O prolific.$O ucons.$O silabs.$O ch340.$O cdc.$O
HFILES=\
../lib/usb.h\
serial.h\
diff -ur /sys/src/cmd/nusb/serial/serial.c /usr/glenda/nusb/serial/serial.c
--- /sys/src/cmd/nusb/serial/serial.c Fri Dec 13 00:31:34 2019
+++ /usr/glenda/nusb/serial/serial.c Wed Jun 10 21:36:54 2020
@@ -621,9 +621,12 @@
{
int i, epin, epout, epintr;
Ep *ep, **eps;
+ int oifc;
+ oifc = ifc;
epintr = epin = epout = -1;
+TOPFINDEPS:
/*
* interfc 0 means start from the start which is equiv to
* iterate through endpoints probably, could be done better
@@ -644,8 +647,13 @@
}
}
dprint(2, "serial[%d]: ep ids: in %d out %d intr %d\n", ifc, epin, epout, epintr);
- if(epin == -1 || epout == -1 || (ser->hasepintr && epintr == -1))
- return -1;
+ if(epin == -1 || epout == -1 || (ser->hasepintr && epintr == -1)){
+ ifc++;
+ if(ifc > 1)
+ return -1;
+ goto TOPFINDEPS;
+ }
+ ifc = oifc;
if(openeps(&ser->p[ifc], epin, epout, epintr) < 0)
return -1;
@@ -714,6 +722,7 @@
extern int slprobe(Serial *ser);
extern int chprobe(Serial *ser);
extern int uconsprobe(Serial *ser);
+extern int cdcprobe(Serial *ser);
void
threadmain(int argc, char* argv[])
@@ -750,7 +759,8 @@
&& ftprobe(ser)
&& slprobe(ser)
&& plprobe(ser)
- && chprobe(ser))
+ && chprobe(ser)
+ && cdcprobe(ser))
sysfatal("no serial devices found");
for(i = 0; i < ser->nifcs; i++){
[-- Attachment #3: cdc.c --]
[-- Type: text/x-csrc, Size: 2398 bytes --]
#include <u.h>
#include <libc.h>
#include <thread.h>
#include <fcall.h>
#include <9p.h>
#include "usb.h"
#include "serial.h"
enum {
ScACM = 2,
AT = 1,
};
static int
cdcsetparam(Serialport *p)
{
int res;
uchar vals[7];
Serial *ser;
ser = p->s;
PUT4(vals, p->baud);
vals[4] = 0;
if(p->stop == 1)
vals[4] = 0;
if(p->stop == 15)
vals[4] = 1;
if(p->stop == 2)
vals[4] = 2;
vals[5] = p->parity;
vals[6] = p->bits;
res = usbcmd(ser->dev, Rh2d | Rclass | Riface, 0x20, 0, 0, vals, 7);
return res;
}
static int
cdcinit(Serialport *p)
{
Serial *ser;
p->baud = 115200;
p->bits = 8;
p->parity = 0;
p->stop = 1;
ser = p->s;
cdcsetparam(p);
incref(ser->dev);
return 0;
}
static int
cdcsetbreak(Serialport *p, int val)
{
Serial *ser;
ser = p->s;
return usbcmd(ser->dev, Rh2d | Rclass | Riface, 0x23, (val != 0? 0xffff: 0x0000), 0, nil, 0);
}
static int
cdcseteps(Serialport *p)
{
devctl(p->epin, "maxpkt 256");
devctl(p->epout, "maxpkt 256");
return 0;
}
static int
cdcsendlines(Serialport *p)
{
if(p->rts)
p->ctlstate |= 0x0002;
else
p->ctlstate &= ~0x0002;
if(p->dtr)
p->ctlstate |= 0x0001;
else
p->ctlstate &= ~0x0001;
return usbcmd(p->s->dev, Rh2d | Rclass | Riface, 0x22, p->ctlstate, 0, nil, 0);
}
static int
cdcclearpipes(Serialport *p)
{
Serial *ser;
ser = p->s;
if(unstall(ser->dev, p->epout, Eout) < 0)
dprint(2, "disk: unstall epout: %r\n");
if(unstall(ser->dev, p->epin, Ein) < 0)
dprint(2, "disk: unstall epin: %r\n");
if(unstall(ser->dev, p->epintr, Ein) < 0)
dprint(2, "disk: unstall epintr: %r\n");
return 0;
}
static int
cdcwait4data(Serialport *p, uchar *data, int count)
{
int n;
qunlock(p->s);
while ((n = read(p->epin->dfd, data, count)) == 0)
;
qlock(p->s);
return n;
}
static Serialops cdcops = {
.init = cdcinit,
.setparam = cdcsetparam,
.setbreak = cdcsetbreak,
.seteps = cdcseteps,
.sendlines = cdcsendlines,
.clearpipes = cdcclearpipes,
.wait4data = cdcwait4data,
};
int
cdcprobe(Serial *ser)
{
int i, c;
ulong csp;
Usbdev *ud = ser->dev->usb;
Ep *ep;
c = 0;
for (i = 0; i < nelem(ud->ep); i++) {
if ((ep = ud->ep[i]) == nil)
continue;
csp = ep->iface->csp;
if (Class(csp) == Clcomms && Subclass(csp) == ScACM && Proto(csp) == AT)
c++;
}
if (c == 0)
return -1;
ser->nifcs = 1;
ser->outhdrsz = 0;
ser->hasepintr = 1;
ser->Serialops = cdcops;
return 0;
}
next reply other threads:[~2020-06-11 7:03 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-11 7:03 Eli Cohen [this message]
2020-06-11 7:17 ` [9front] " Alex Musolino
2020-06-11 7:19 ` Eli Cohen
2020-06-11 7:29 ` Alex Musolino
2020-06-11 7:36 ` Eli Cohen
2020-06-11 7:57 ` Eli Cohen
2020-06-11 12:15 ` cinap_lenrek
2020-06-11 14:08 ` Eli Cohen
2020-06-11 17:10 ` cinap_lenrek
2020-06-12 1:28 ` Eli Cohen
2020-06-12 18:02 ` cinap_lenrek
2020-06-12 22:15 ` Eli Cohen
2020-06-13 14:03 ` cinap_lenrek
2020-06-13 14:18 ` Eli Cohen
2020-06-13 15:37 ` cinap_lenrek
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAHwi9bz7qpA11VWd0r6nDdoseM_qiwR7rxwpdN8p5N74j0mO6g@mail.gmail.com \
--to=echoline@gmail.com \
--cc=9front@9front.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).