From e5833b6a09786844ae09f389d768accec9678026 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 8 Sep 2015 12:28:44 +0000 Subject: Disconnect handling in SDU driver. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8287 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/src/serial_usb.c | 43 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) (limited to 'os/hal/src/serial_usb.c') diff --git a/os/hal/src/serial_usb.c b/os/hal/src/serial_usb.c index dc0e803a8..c32a17376 100644 --- a/os/hal/src/serial_usb.c +++ b/os/hal/src/serial_usb.c @@ -56,43 +56,67 @@ static cdc_linecoding_t linecoding = { static size_t write(void *ip, const uint8_t *bp, size_t n) { + if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE) + return 0; + return oqWriteTimeout(&((SerialUSBDriver *)ip)->oqueue, 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 iqReadTimeout(&((SerialUSBDriver *)ip)->iqueue, 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 oqPutTimeout(&((SerialUSBDriver *)ip)->oqueue, b, TIME_INFINITE); } static msg_t get(void *ip) { + if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE) + return MSG_RESET; + return iqGetTimeout(&((SerialUSBDriver *)ip)->iqueue, 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 oqPutTimeout(&((SerialUSBDriver *)ip)->oqueue, b, timeout); } static msg_t gett(void *ip, systime_t timeout) { + if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE) + return MSG_RESET; + return iqGetTimeout(&((SerialUSBDriver *)ip)->iqueue, 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 oqWriteTimeout(&((SerialUSBDriver *)ip)->oqueue, 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 iqReadTimeout(&((SerialUSBDriver *)ip)->iqueue, bp, n, timeout); } @@ -252,12 +276,27 @@ void sduStop(SerialUSBDriver *sdup) { } sdup->state = SDU_STOP; + /* Enforces a disconnection.*/ + sduDisconnectI(sdup); + osalOsRescheduleS(); + osalSysUnlock(); +} + +/** + * @brief USB device disconnection handler. + * @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 sduDisconnectI(SerialUSBDriver *sdup) { + /* Queues reset in order to signal the driver stop to the application.*/ chnAddFlagsI(sdup, CHN_DISCONNECTED); iqResetI(&sdup->iqueue); iqResetI(&sdup->oqueue); - osalOsRescheduleS(); - osalSysUnlock(); } /** -- cgit v1.2.3