aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/src/hal_serial_usb.c
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2016-11-03 12:43:09 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2016-11-03 12:43:09 +0000
commite1d8e5357927f0748fef013fb4bddebe781c60a8 (patch)
tree389cb8d73a94f53adc36d690fb8336d29cca55ea /os/hal/src/hal_serial_usb.c
parent13537cb7240240e6c7f915aa4d2aa6772034003b (diff)
downloadChibiOS-e1d8e5357927f0748fef013fb4bddebe781c60a8.tar.gz
ChibiOS-e1d8e5357927f0748fef013fb4bddebe781c60a8.tar.bz2
ChibiOS-e1d8e5357927f0748fef013fb4bddebe781c60a8.zip
Tentative USB suspend fix.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9898 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os/hal/src/hal_serial_usb.c')
-rw-r--r--os/hal/src/hal_serial_usb.c73
1 files changed, 33 insertions, 40 deletions
diff --git a/os/hal/src/hal_serial_usb.c b/os/hal/src/hal_serial_usb.c
index 480e4da4f..70f3c9179 100644
--- a/os/hal/src/hal_serial_usb.c
+++ b/os/hal/src/hal_serial_usb.c
@@ -84,75 +84,43 @@ static bool sdu_start_receive(SerialUSBDriver *sdup) {
static size_t write(void *ip, const uint8_t *bp, size_t n) {
- if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE) {
- return 0;
- }
-
return obqWriteTimeout(&((SerialUSBDriver *)ip)->obqueue, bp,
n, TIME_INFINITE);
}
static size_t read(void *ip, uint8_t *bp, size_t n) {
- if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE) {
- return 0;
- }
-
return ibqReadTimeout(&((SerialUSBDriver *)ip)->ibqueue, bp,
n, TIME_INFINITE);
}
static msg_t put(void *ip, uint8_t b) {
- if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE) {
- return MSG_RESET;
- }
-
return obqPutTimeout(&((SerialUSBDriver *)ip)->obqueue, b, TIME_INFINITE);
}
static msg_t get(void *ip) {
- if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE) {
- return MSG_RESET;
- }
-
return ibqGetTimeout(&((SerialUSBDriver *)ip)->ibqueue, TIME_INFINITE);
}
static msg_t putt(void *ip, uint8_t b, systime_t timeout) {
- if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE) {
- return MSG_RESET;
- }
-
return obqPutTimeout(&((SerialUSBDriver *)ip)->obqueue, b, timeout);
}
static msg_t gett(void *ip, systime_t timeout) {
- if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE) {
- return MSG_RESET;
- }
-
return ibqGetTimeout(&((SerialUSBDriver *)ip)->ibqueue, timeout);
}
static size_t writet(void *ip, const uint8_t *bp, size_t n, systime_t timeout) {
- if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE) {
- return 0;
- }
-
return obqWriteTimeout(&((SerialUSBDriver *)ip)->obqueue, bp, n, timeout);
}
static size_t readt(void *ip, uint8_t *bp, size_t n, systime_t timeout) {
- if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE) {
- return 0;
- }
-
return ibqReadTimeout(&((SerialUSBDriver *)ip)->ibqueue, bp, n, timeout);
}
@@ -226,10 +194,10 @@ void sduObjectInit(SerialUSBDriver *sdup) {
sdup->vmt = &vmt;
osalEventObjectInit(&sdup->event);
sdup->state = SDU_STOP;
- ibqObjectInit(&sdup->ibqueue, sdup->ib,
+ ibqObjectInit(&sdup->ibqueue, true, sdup->ib,
SERIAL_USB_BUFFERS_SIZE, SERIAL_USB_BUFFERS_NUMBER,
ibnotify, sdup);
- obqObjectInit(&sdup->obqueue, sdup->ob,
+ obqObjectInit(&sdup->obqueue, true, sdup->ob,
SERIAL_USB_BUFFERS_SIZE, SERIAL_USB_BUFFERS_NUMBER,
obnotify, sdup);
}
@@ -289,14 +257,19 @@ void sduStop(SerialUSBDriver *sdup) {
sdup->state = SDU_STOP;
/* Enforces a disconnection.*/
- sduDisconnectI(sdup);
+ chnAddFlagsI(sdup, CHN_DISCONNECTED);
+ ibqResetI(&sdup->ibqueue);
+ obqResetI(&sdup->obqueue);
osalOsRescheduleS();
osalSysUnlock();
}
/**
- * @brief USB device disconnection handler.
+ * @brief USB device suspend handler.
+ * @details Generates a @p CHN_DISCONNECT event and puts queues in
+ * non-blocking mode, this way the application cannot get stuck
+ * in the middle of an I/O operations.
* @note If this function is not called from an ISR then an explicit call
* to @p osalOsRescheduleS() in necessary afterward.
*
@@ -304,12 +277,30 @@ void sduStop(SerialUSBDriver *sdup) {
*
* @iclass
*/
-void sduDisconnectI(SerialUSBDriver *sdup) {
+void sduSuspendHookI(SerialUSBDriver *sdup) {
- /* Queues reset in order to signal the driver stop to the application.*/
chnAddFlagsI(sdup, CHN_DISCONNECTED);
- ibqResetI(&sdup->ibqueue);
- obqResetI(&sdup->obqueue);
+ bqSuspendI(&sdup->ibqueue);
+ bqSuspendI(&sdup->obqueue);
+}
+
+/**
+ * @brief USB device wakeup handler.
+ * @details Generates a @p CHN_CONNECT event and resumes normal queues
+ * operations.
+ *
+ * @note If this function is not called from an ISR then an explicit call
+ * to @p osalOsRescheduleS() in necessary afterward.
+ *
+ * @param[in] sdup pointer to a @p SerialUSBDriver object
+ *
+ * @iclass
+ */
+void sduWakeupHookI(SerialUSBDriver *sdup) {
+
+ chnAddFlagsI(sdup, CHN_CONNECTED);
+ bqResumeX(&sdup->ibqueue);
+ bqResumeX(&sdup->obqueue);
}
/**
@@ -322,7 +313,9 @@ void sduDisconnectI(SerialUSBDriver *sdup) {
void sduConfigureHookI(SerialUSBDriver *sdup) {
ibqResetI(&sdup->ibqueue);
+ bqResumeX(&sdup->ibqueue);
obqResetI(&sdup->obqueue);
+ bqResumeX(&sdup->obqueue);
chnAddFlagsI(sdup, CHN_CONNECTED);
(void) sdu_start_receive(sdup);
}