aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/src
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2012-06-11 16:54:35 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2012-06-11 16:54:35 +0000
commitd094e348c5d1a3785289c69c5185bbaca1257de8 (patch)
tree982d1606d57103c8ee2d38e9a11d161a65716640 /os/hal/src
parentc762926b68f6a6c7f1e71b8acf9b1dd29d6e481f (diff)
downloadChibiOS-d094e348c5d1a3785289c69c5185bbaca1257de8.tar.gz
ChibiOS-d094e348c5d1a3785289c69c5185bbaca1257de8.tar.bz2
ChibiOS-d094e348c5d1a3785289c69c5185bbaca1257de8.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4266 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/src')
-rw-r--r--os/hal/src/serial.c4
-rw-r--r--os/hal/src/serial_usb.c115
2 files changed, 49 insertions, 70 deletions
diff --git a/os/hal/src/serial.c b/os/hal/src/serial.c
index 3f06025c6..5b883e16a 100644
--- a/os/hal/src/serial.c
+++ b/os/hal/src/serial.c
@@ -149,8 +149,8 @@ void sdObjectInit(SerialDriver *sdp, qnotify_t inotify, qnotify_t onotify) {
chEvtInit(&sdp->event);
sdp->flags = CHN_NO_ERROR;
sdp->state = SD_STOP;
- chIQInit(&sdp->iqueue, sdp->ib, SERIAL_BUFFERS_SIZE, inotify);
- chOQInit(&sdp->oqueue, sdp->ob, SERIAL_BUFFERS_SIZE, onotify);
+ chIQInit(&sdp->iqueue, sdp->ib, SERIAL_BUFFERS_SIZE, inotify, sdp);
+ chOQInit(&sdp->oqueue, sdp->ob, SERIAL_BUFFERS_SIZE, onotify, sdp);
}
/**
diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c
index 7f1658812..5fec52a68 100644
--- a/os/hal/src/serial_usb.c
+++ b/os/hal/src/serial_usb.c
@@ -117,59 +117,47 @@ static const struct SerialUSBDriverVMT vmt = {
* @brief Notification of data removed from the input queue.
*/
static void inotify(GenericQueue *qp) {
- SerialUSBDriver *sdup = (SerialUSBDriver *)qp->q_wrptr;
+ size_t n, maxsize;
+ SerialUSBDriver *sdup = chQGetLink(qp);
-#if 0
- /* Writes to the input queue can only happen when the queue has been
- emptied, then a whole packet is loaded in the queue.*/
+ /* 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) &&
- chIQIsEmptyI(&sdup->iqueue)) {
+ ((n = chIQGetEmptyI(&sdup->iqueue)) >= maxsize)) {
chSysUnlock();
- /* Unlocked to make the potentially long read operation preemptable.*/
- size_t n = usbReadPacketBuffer(sdup->config->usbp,
- USB_CDC_DATA_AVAILABLE_EP,
- sdup->iqueue.q_buffer,
- SERIAL_USB_BUFFERS_SIZE);
+ n = (n / maxsize) * maxsize;
+ usbPrepareQueuedReceive(sdup->config->usbp,
+ USB_CDC_DATA_AVAILABLE_EP,
+ &sdup->iqueue, n);
chSysLock();
usbStartReceiveI(sdup->config->usbp, USB_CDC_DATA_AVAILABLE_EP);
- chnAddFlagsI(sdup, CHN_INPUT_AVAILABLE);
- sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer;
- sdup->iqueue.q_counter = n;
- while (notempty(&sdup->iqueue.q_waiting))
- chSchReadyI(fifo_remove(&sdup->iqueue.q_waiting))->p_u.rdymsg = Q_OK;
}
-#endif
}
/**
* @brief Notification of data inserted into the output queue.
*/
static void onotify(GenericQueue *qp) {
- SerialUSBDriver *sdup = (SerialUSBDriver *)qp->q_rdptr;
size_t n;
+ SerialUSBDriver *sdup = chQGetLink(qp);
-#if 0
- /* If there is any data in the output queue then it is sent within a
- single packet and the queue is emptied.*/
- n = chOQGetFullI(&sdup->oqueue);
- if (!usbGetTransmitStatusI(sdup->config->usbp, USB_CDC_DATA_REQUEST_EP)) {
+ /* 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) &&
+ ((n = chOQGetFullI(&sdup->oqueue)) > 0)) {
chSysUnlock();
- /* Unlocked to make the potentially long write operation preemptable.*/
- usbWritePacketBuffer(sdup->config->usbp, USB_CDC_DATA_REQUEST_EP,
- sdup->oqueue.q_buffer, n);
+ usbPrepareQueuedTransmit(sdup->config->usbp,
+ USB_CDC_DATA_REQUEST_EP,
+ &sdup->oqueue, n);
chSysLock();
usbStartTransmitI(sdup->config->usbp, USB_CDC_DATA_REQUEST_EP);
- chnAddFlagsI(sdup, CHN_OUTPUT_EMPTY);
- sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer;
- sdup->oqueue.q_counter = chQSizeI(&sdup->oqueue);
- while (notempty(&sdup->oqueue.q_waiting))
- chSchReadyI(fifo_remove(&sdup->oqueue.q_waiting))->p_u.rdymsg = Q_OK;
}
-#endif
}
/*===========================================================================*/
@@ -201,12 +189,8 @@ void sduObjectInit(SerialUSBDriver *sdup) {
chEvtInit(&sdup->event);
sdup->flags = CHN_NO_ERROR;
sdup->state = SDU_STOP;
- chIQInit(&sdup->iqueue, sdup->ib, SERIAL_USB_BUFFERS_SIZE, inotify);
- chOQInit(&sdup->oqueue, sdup->ob, SERIAL_USB_BUFFERS_SIZE, onotify);
- /* This is a dirty trick but those pointers are never used because queues
- are accessed in block mode from the low level.*/
- sdup->iqueue.q_wrptr = (uint8_t *)sdup;
- sdup->oqueue.q_rdptr = (uint8_t *)sdup;
+ chIQInit(&sdup->iqueue, sdup->ib, SERIAL_USB_BUFFERS_SIZE, inotify, sdup);
+ chOQInit(&sdup->oqueue, sdup->ob, SERIAL_USB_BUFFERS_SIZE, onotify, sdup);
}
/**
@@ -299,32 +283,28 @@ bool_t sduRequestsHook(USBDriver *usbp) {
* @param[in] ep endpoint number
*/
void sduDataTransmitted(USBDriver *usbp, usbep_t ep) {
- SerialUSBDriver *sdup = usbp->param;
size_t n;
+ SerialUSBDriver *sdup = usbp->param;
+
+ (void)ep;
-#if 0
+ chnAddFlagsI(sdup, CHN_OUTPUT_EMPTY);
chSysLockFromIsr();
- /* If there is any data in the output queue then it is sent within a
- single packet and the queue is emptied.*/
- n = chOQGetFullI(&sdup->oqueue);
- if (n > 0) {
+
+ if ((n = chOQGetFullI(&sdup->oqueue)) > 0) {
/* The endpoint cannot be busy, we are in the context of the callback,
so it is safe to transmit without a check.*/
chSysUnlockFromIsr();
- /* Unlocked to make the potentially long write operation preemptable.*/
- usbWritePacketBuffer(usbp, ep, sdup->oqueue.q_buffer, n);
+ usbPrepareQueuedTransmit(sdup->config->usbp,
+ USB_CDC_DATA_REQUEST_EP,
+ &sdup->oqueue, n);
chSysLockFromIsr();
- usbStartTransmitI(usbp, ep);
- chnAddFlagsI(sdup, CHN_OUTPUT_EMPTY);
- sdup->oqueue.q_wrptr = sdup->oqueue.q_buffer;
- sdup->oqueue.q_counter = chQSizeI(&sdup->oqueue);
- while (notempty(&sdup->oqueue.q_waiting))
- chSchReadyI(fifo_remove(&sdup->oqueue.q_waiting))->p_u.rdymsg = Q_OK;
+ usbStartTransmitI(sdup->config->usbp, USB_CDC_DATA_REQUEST_EP);
}
+
chSysUnlockFromIsr();
-#endif
}
/**
@@ -336,33 +316,32 @@ void sduDataTransmitted(USBDriver *usbp, usbep_t ep) {
* @param[in] ep endpoint number
*/
void sduDataReceived(USBDriver *usbp, usbep_t ep) {
+ size_t n, maxsize;
SerialUSBDriver *sdup = usbp->param;
-#if 0
+ (void)ep;
+
+ chnAddFlagsI(sdup, CHN_INPUT_AVAILABLE);
chSysLockFromIsr();
- /* Writes to the input queue can only happen when the queue has been
- emptied, then a whole packet is loaded in the queue.*/
- if (chIQIsEmptyI(&sdup->iqueue)) {
+
+ /* Writes to the input queue can only happen when there is enough space
+ to hold at least one packet.*/
+ maxsize = sdup->config->usbp->epc[USB_CDC_DATA_AVAILABLE_EP]->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.*/
- size_t n;
-
chSysUnlockFromIsr();
- /* Unlocked to make the potentially long write operation preemptable.*/
- n = usbReadPacketBuffer(usbp, ep, sdup->iqueue.q_buffer,
- SERIAL_USB_BUFFERS_SIZE);
+ n = (n / maxsize) * maxsize;
+ usbPrepareQueuedReceive(sdup->config->usbp,
+ USB_CDC_DATA_AVAILABLE_EP,
+ &sdup->iqueue, n);
chSysLockFromIsr();
- usbStartReceiveI(usbp, ep);
- chnAddFlagsI(sdup, CHN_INPUT_AVAILABLE);
- sdup->iqueue.q_rdptr = sdup->iqueue.q_buffer;
- sdup->iqueue.q_counter = n;
- while (notempty(&sdup->iqueue.q_waiting))
- chSchReadyI(fifo_remove(&sdup->iqueue.q_waiting))->p_u.rdymsg = Q_OK;
+ usbStartReceiveI(sdup->config->usbp, USB_CDC_DATA_AVAILABLE_EP);
}
+
chSysUnlockFromIsr();
-#endif
}
/**