After the test of DualCDC with STM32F4 with low success, in waiting for solution of the bug, I trying my firmware DualCDC with PIC32MX.
Without changes in source code, but only in Makefile I tried to compile, my old test DualCDC for PIC32MX, and compile without problems, ChibiOS is great for this.
My device is detected in my linux system with 2 ttyACM, so my descriptor was correct, but I have a doubt: how can I associate new ttyACM at SerialUSBDriver?
In my example there is a SerialUSBDriver SDU1 and I can read and write with first ttyACM, but I don't know how to create a new SerialUSBDriver.
I should be associate new endpoints, but I don't understand if is possible with latest ChibiOS 2.5.2
Thank you
[DONE] DualCDC associate new SerialUSBDriver
Moderators: RoccoMarco, lbednarz, utzig, tfAteba, barthess
Re: DualCDC associate new SerialUSBDriver
I give me a first reply alone, I think I need to rewrite ./os/hal/src/serial_usb.c for manage multiple SerialUSBDriver. There are static definition of endpoints.
- Giovanni
- Site Admin
- Posts: 14444
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1074 times
- Been thanked: 921 times
- Contact:
Re: DualCDC associate new SerialUSBDriver
Good point, it appears to not be possible, descriptor numbers should be associated to the configuration structure instead of being statically configured.
I will look into this, I already planned to rework the serial_usb driver.
Giovanni
I will look into this, I already planned to rework the serial_usb driver.
Giovanni
Re: [TODO] DualCDC associate new SerialUSBDriver
I tried to develop a patch, very expiremental. Works but is not perfect. I added a field (Endpoint Data) in SerialUSBDriver, so endpoint data is not static.
In my test I create 2 shell one for each serial, with different commands.
First serial has problem in receive data, I receveid data only after I sent data, second serial is ok.
After some tests about five minutes, first serial stop to work and second serial is yet ok.
main.c
Maybe 2 shell command is a problem, I will test with only one shell.
In my test I create 2 shell one for each serial, with different commands.
First serial has problem in receive data, I receveid data only after I sent data, second serial is ok.
After some tests about five minutes, first serial stop to work and second serial is yet ok.
Code: Select all
diff --git a/os/hal/include/serial_usb.h b/os/hal/include/serial_usb.h
index cdde81e..abdcb7a 100644
--- a/os/hal/include/serial_usb.h
+++ b/os/hal/include/serial_usb.h
@@ -111,7 +111,8 @@ typedef struct {
uint8_t ob[SERIAL_USB_BUFFERS_SIZE]; \
/* End of the mandatory fields.*/ \
/* Current configuration data.*/ \
- const SerialUSBConfig *config;
+ const SerialUSBConfig *config; \
+ uint8_t iEpData;
/**
* @brief @p SerialUSBDriver specific methods.
diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c
index 7b7d255..d2bf4c3 100644
--- a/os/hal/src/serial_usb.c
+++ b/os/hal/src/serial_usb.c
@@ -123,18 +123,18 @@ static void inotify(GenericQueue *qp) {
/* If there is in the queue enough space to hold at least one packet and
a transaction is not yet started then a new transaction is started for
the available space.*/
- maxsize = sdup->config->usbp->epc[USB_CDC_DATA_AVAILABLE_EP]->out_maxsize;
- if (!usbGetReceiveStatusI(sdup->config->usbp, USB_CDC_DATA_AVAILABLE_EP) &&
+ maxsize = sdup->config->usbp->epc[sdup->iEpData]->out_maxsize;
+ if (!usbGetReceiveStatusI(sdup->config->usbp, sdup->iEpData) &&
((n = chIQGetEmptyI(&sdup->iqueue)) >= maxsize)) {
chSysUnlock();
n = (n / maxsize) * maxsize;
usbPrepareQueuedReceive(sdup->config->usbp,
- USB_CDC_DATA_AVAILABLE_EP,
+ sdup->iEpData,
&sdup->iqueue, n);
chSysLock();
- usbStartReceiveI(sdup->config->usbp, USB_CDC_DATA_AVAILABLE_EP);
+ usbStartReceiveI(sdup->config->usbp, sdup->iEpData);
}
}
@@ -152,16 +152,16 @@ static void onotify(GenericQueue *qp) {
/* If there is not an ongoing transaction and the output queue contains
data then a new transaction is started.*/
- if (!usbGetTransmitStatusI(sdup->config->usbp, USB_CDC_DATA_REQUEST_EP) &&
+ if (!usbGetTransmitStatusI(sdup->config->usbp, sdup->iEpData) &&
((n = chOQGetFullI(&sdup->oqueue)) > 0)) {
chSysUnlock();
usbPrepareQueuedTransmit(sdup->config->usbp,
- USB_CDC_DATA_REQUEST_EP,
+ sdup->iEpData,
&sdup->oqueue, n);
chSysLock();
- usbStartTransmitI(sdup->config->usbp, USB_CDC_DATA_REQUEST_EP);
+ usbStartTransmitI(sdup->config->usbp, sdup->iEpData);
}
}
@@ -255,9 +255,9 @@ void sduConfigureHookI(USBDriver *usbp) {
chnAddFlagsI(sdup, CHN_CONNECTED);
/* Starts the first OUT transaction immediately.*/
- usbPrepareQueuedReceive(usbp, USB_CDC_DATA_AVAILABLE_EP, &sdup->iqueue,
- usbp->epc[USB_CDC_DATA_AVAILABLE_EP]->out_maxsize);
- usbStartReceiveI(usbp, USB_CDC_DATA_AVAILABLE_EP);
+ usbPrepareQueuedReceive(usbp, sdup->iEpData, &sdup->iqueue,
+ usbp->epc[sdup->iEpData]->out_maxsize);
+ usbStartReceiveI(usbp, sdup->iEpData);
}
/**
@@ -360,7 +360,7 @@ void sduDataReceived(USBDriver *usbp, usbep_t ep) {
/* Writes to the input queue can only happen when there is enough space
to hold at least one packet.*/
- maxsize = usbp->epc[USB_CDC_DATA_AVAILABLE_EP]->out_maxsize;
+ maxsize = usbp->epc[sdup->iEpData]->out_maxsize;
if ((n = chIQGetEmptyI(&sdup->iqueue)) >= maxsize) {
/* The endpoint cannot be busy, we are in the context of the callback,
so a packet is in the buffer for sure.*/
main.c
Code: Select all
SDU1.iEpData = 1;
SDU2.iEpData = 3;
/*
* Initializes a serial-over-USB CDC driver.
*/
sduObjectInit(&SDU1);
sduStart(&SDU1, &serUsbCfg);
sduObjectInit(&SDU2);
sduStart(&SDU2, &serUsbCfg);
Maybe 2 shell command is a problem, I will test with only one shell.
- Giovanni
- Site Admin
- Posts: 14444
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1074 times
- Been thanked: 921 times
- Contact:
Re: [TODO] DualCDC associate new SerialUSBDriver
Hi,
The endpoint number(s) should go in the configuration structure, except for that it looks good.
Giovanni
The endpoint number(s) should go in the configuration structure, except for that it looks good.
Giovanni
Re: [TODO] DualCDC associate new SerialUSBDriver
Hi Giovanni,
new patch
for definition of SerialUSBConfig become:
I have the same problem with first serial in flush data when there are 2 serials.
With 2 CDC without initialize the second serial (sduObjectInit and sduStart), the first serial works very well. So I think my simple patch don't make problems to previuos version of USB CDC Serial.
Thank you
new patch
Code: Select all
diff --git a/os/hal/include/serial_usb.h b/os/hal/include/serial_usb.h
index cdde81e..955a641 100644
--- a/os/hal/include/serial_usb.h
+++ b/os/hal/include/serial_usb.h
@@ -92,6 +92,7 @@ typedef struct {
* @brief USB driver to use.
*/
USBDriver *usbp;
+ uint8_t endpdata;
} SerialUSBConfig;
/**
diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c
index 7b7d255..90dea4d 100644
--- a/os/hal/src/serial_usb.c
+++ b/os/hal/src/serial_usb.c
@@ -123,18 +123,18 @@ static void inotify(GenericQueue *qp) {
/* If there is in the queue enough space to hold at least one packet and
a transaction is not yet started then a new transaction is started for
the available space.*/
- maxsize = sdup->config->usbp->epc[USB_CDC_DATA_AVAILABLE_EP]->out_maxsize;
- if (!usbGetReceiveStatusI(sdup->config->usbp, USB_CDC_DATA_AVAILABLE_EP) &&
+ maxsize = sdup->config->usbp->epc[sdup->config->endpdata]->out_maxsize;
+ if (!usbGetReceiveStatusI(sdup->config->usbp, sdup->config->endpdata) &&
((n = chIQGetEmptyI(&sdup->iqueue)) >= maxsize)) {
chSysUnlock();
n = (n / maxsize) * maxsize;
usbPrepareQueuedReceive(sdup->config->usbp,
- USB_CDC_DATA_AVAILABLE_EP,
+ sdup->config->endpdata,
&sdup->iqueue, n);
chSysLock();
- usbStartReceiveI(sdup->config->usbp, USB_CDC_DATA_AVAILABLE_EP);
+ usbStartReceiveI(sdup->config->usbp, sdup->config->endpdata);
}
}
@@ -152,16 +152,16 @@ static void onotify(GenericQueue *qp) {
/* If there is not an ongoing transaction and the output queue contains
data then a new transaction is started.*/
- if (!usbGetTransmitStatusI(sdup->config->usbp, USB_CDC_DATA_REQUEST_EP) &&
+ if (!usbGetTransmitStatusI(sdup->config->usbp, sdup->config->endpdata) &&
((n = chOQGetFullI(&sdup->oqueue)) > 0)) {
chSysUnlock();
usbPrepareQueuedTransmit(sdup->config->usbp,
- USB_CDC_DATA_REQUEST_EP,
+ sdup->config->endpdata,
&sdup->oqueue, n);
chSysLock();
- usbStartTransmitI(sdup->config->usbp, USB_CDC_DATA_REQUEST_EP);
+ usbStartTransmitI(sdup->config->usbp, sdup->config->endpdata);
}
}
@@ -255,9 +255,9 @@ void sduConfigureHookI(USBDriver *usbp) {
chnAddFlagsI(sdup, CHN_CONNECTED);
/* Starts the first OUT transaction immediately.*/
- usbPrepareQueuedReceive(usbp, USB_CDC_DATA_AVAILABLE_EP, &sdup->iqueue,
- usbp->epc[USB_CDC_DATA_AVAILABLE_EP]->out_maxsize);
- usbStartReceiveI(usbp, USB_CDC_DATA_AVAILABLE_EP);
+ usbPrepareQueuedReceive(usbp, sdup->config->endpdata, &sdup->iqueue,
+ usbp->epc[sdup->config->endpdata]->out_maxsize);
+ usbStartReceiveI(usbp, sdup->config->endpdata);
}
/**
@@ -360,7 +360,7 @@ void sduDataReceived(USBDriver *usbp, usbep_t ep) {
/* Writes to the input queue can only happen when there is enough space
to hold at least one packet.*/
- maxsize = usbp->epc[USB_CDC_DATA_AVAILABLE_EP]->out_maxsize;
+ maxsize = usbp->epc[sdup->config->endpdata]->out_maxsize;
if ((n = chIQGetEmptyI(&sdup->iqueue)) >= maxsize) {
/* The endpoint cannot be busy, we are in the context of the callback,
so a packet is in the buffer for sure.*/
for definition of SerialUSBConfig become:
Code: Select all
const SerialUSBConfig serUsbCfg = {
&USBD1,
1 // endpoint data
};
const SerialUSBConfig serUsbCfg2 = {
&USBD1,
3 // endpoint data
};
I have the same problem with first serial in flush data when there are 2 serials.
With 2 CDC without initialize the second serial (sduObjectInit and sduStart), the first serial works very well. So I think my simple patch don't make problems to previuos version of USB CDC Serial.
Thank you
- Giovanni
- Site Admin
- Posts: 14444
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1074 times
- Been thanked: 921 times
- Contact:
Re: [TODO] DualCDC associate new SerialUSBDriver
Hi,
I made changes to the Serial_USB driver along those lines, I had to specify all three endpoints because it is not guaranteed that IN and OUT can have the same number and the interrupt endpoints has to be specified too.
Please verify if the changes indeed fix your problems.
Giovanni
I made changes to the Serial_USB driver along those lines, I had to specify all three endpoints because it is not guaranteed that IN and OUT can have the same number and the interrupt endpoints has to be specified too.
Please verify if the changes indeed fix your problems.
Giovanni
Re: [DONE] DualCDC associate new SerialUSBDriver
Hi Giovanni,
thank you for your update. I still have problems with flush data on first serial.
I tried to disable the second serial and all work very well.
Sure with your patch serial usb work in all custom implementations.
thank you for your update. I still have problems with flush data on first serial.
I tried to disable the second serial and all work very well.
Sure with your patch serial usb work in all custom implementations.
- Giovanni
- Site Admin
- Posts: 14444
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1074 times
- Been thanked: 921 times
- Contact:
Re: [DONE] DualCDC associate new SerialUSBDriver
Hi,
I am not sure to understand the problem with the flush data, could you give an example?
Giovanni
I am not sure to understand the problem with the flush data, could you give an example?
Giovanni
Re: [DONE] DualCDC associate new SerialUSBDriver
In my test source code I have
On SDU1 there is attached the shell. When I open the serial port with my program (minicom for linux or hyperterminal for windows) I expect a prompt of the shell, but for get it I need to send data with ENTER key. When I send the command info, this return many rows, I need to send many ENTER key for get all the output. I think there is a problem in flush data. In my shell there is the command write, I took the source from your testhal. In my example this command write on SDU2, and work very well.
I attached 2 shell. The shell on SDU2 works, I got data without send ENTER key, as it should be normally, the shell on SDU1 has problem with flush.
The problem is not on SDU1 but on the first call to sduObjectInit/sduStart. I think the second call to sduObjectInit/sduStart overwrite something.
With this code
The shell on SDU1 works very well, but the command write doesn't work (1° test), the shell on SDU2 (2° test) has problem with flush data.
If you have some board with PIC32 I can give you my simple test project. I can't test on STM32 because there is the problem on descriptor length.
Thank you
Code: Select all
sduObjectInit(&SDU1);
sduStart(&SDU1, &serUsbCfg);
sduObjectInit(&SDU2);
sduStart(&SDU2, &serUsbCfg2);
On SDU1 there is attached the shell. When I open the serial port with my program (minicom for linux or hyperterminal for windows) I expect a prompt of the shell, but for get it I need to send data with ENTER key. When I send the command info, this return many rows, I need to send many ENTER key for get all the output. I think there is a problem in flush data. In my shell there is the command write, I took the source from your testhal. In my example this command write on SDU2, and work very well.
I attached 2 shell. The shell on SDU2 works, I got data without send ENTER key, as it should be normally, the shell on SDU1 has problem with flush.
The problem is not on SDU1 but on the first call to sduObjectInit/sduStart. I think the second call to sduObjectInit/sduStart overwrite something.
With this code
Code: Select all
sduObjectInit(&SDU2);
sduStart(&SDU2, &serUsbCfg2);
sduObjectInit(&SDU1);
sduStart(&SDU1, &serUsbCfg);
The shell on SDU1 works very well, but the command write doesn't work (1° test), the shell on SDU2 (2° test) has problem with flush data.
If you have some board with PIC32 I can give you my simple test project. I can't test on STM32 because there is the problem on descriptor length.
Thank you
Who is online
Users browsing this forum: No registered users and 22 guests