Disconnect handling in SDU driver.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8287 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
aa7557a5f2
commit
e5833b6a09
|
@ -247,6 +247,7 @@ extern "C" {
|
||||||
void sduObjectInit(SerialUSBDriver *sdup);
|
void sduObjectInit(SerialUSBDriver *sdup);
|
||||||
void sduStart(SerialUSBDriver *sdup, const SerialUSBConfig *config);
|
void sduStart(SerialUSBDriver *sdup, const SerialUSBConfig *config);
|
||||||
void sduStop(SerialUSBDriver *sdup);
|
void sduStop(SerialUSBDriver *sdup);
|
||||||
|
void sduDisconnectI(SerialUSBDriver *sdup);
|
||||||
void sduConfigureHookI(SerialUSBDriver *sdup);
|
void sduConfigureHookI(SerialUSBDriver *sdup);
|
||||||
bool sduRequestsHook(USBDriver *usbp);
|
bool sduRequestsHook(USBDriver *usbp);
|
||||||
void sduDataTransmitted(USBDriver *usbp, usbep_t ep);
|
void sduDataTransmitted(USBDriver *usbp, usbep_t ep);
|
||||||
|
|
|
@ -56,43 +56,67 @@ static cdc_linecoding_t linecoding = {
|
||||||
|
|
||||||
static size_t write(void *ip, const uint8_t *bp, size_t n) {
|
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,
|
return oqWriteTimeout(&((SerialUSBDriver *)ip)->oqueue, bp,
|
||||||
n, TIME_INFINITE);
|
n, TIME_INFINITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t read(void *ip, uint8_t *bp, size_t n) {
|
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,
|
return iqReadTimeout(&((SerialUSBDriver *)ip)->iqueue, bp,
|
||||||
n, TIME_INFINITE);
|
n, TIME_INFINITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static msg_t put(void *ip, uint8_t b) {
|
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);
|
return oqPutTimeout(&((SerialUSBDriver *)ip)->oqueue, b, TIME_INFINITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static msg_t get(void *ip) {
|
static msg_t get(void *ip) {
|
||||||
|
|
||||||
|
if (usbGetDriverStateI(((SerialUSBDriver *)ip)->config->usbp) != USB_ACTIVE)
|
||||||
|
return MSG_RESET;
|
||||||
|
|
||||||
return iqGetTimeout(&((SerialUSBDriver *)ip)->iqueue, TIME_INFINITE);
|
return iqGetTimeout(&((SerialUSBDriver *)ip)->iqueue, TIME_INFINITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static msg_t putt(void *ip, uint8_t b, systime_t timeout) {
|
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);
|
return oqPutTimeout(&((SerialUSBDriver *)ip)->oqueue, b, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
static msg_t gett(void *ip, systime_t 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);
|
return iqGetTimeout(&((SerialUSBDriver *)ip)->iqueue, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t writet(void *ip, const uint8_t *bp, size_t n, systime_t 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);
|
return oqWriteTimeout(&((SerialUSBDriver *)ip)->oqueue, bp, n, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t readt(void *ip, uint8_t *bp, size_t n, systime_t 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);
|
return iqReadTimeout(&((SerialUSBDriver *)ip)->iqueue, bp, n, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,12 +276,27 @@ void sduStop(SerialUSBDriver *sdup) {
|
||||||
}
|
}
|
||||||
sdup->state = SDU_STOP;
|
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.*/
|
/* Queues reset in order to signal the driver stop to the application.*/
|
||||||
chnAddFlagsI(sdup, CHN_DISCONNECTED);
|
chnAddFlagsI(sdup, CHN_DISCONNECTED);
|
||||||
iqResetI(&sdup->iqueue);
|
iqResetI(&sdup->iqueue);
|
||||||
iqResetI(&sdup->oqueue);
|
iqResetI(&sdup->oqueue);
|
||||||
osalOsRescheduleS();
|
|
||||||
osalSysUnlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -73,6 +73,9 @@
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
|
|
||||||
*** 3.1.0 ***
|
*** 3.1.0 ***
|
||||||
|
- HAL: Modified the serial-USB driver to reject write/read attempts if the
|
||||||
|
underlying USB is not in active state. In case of disconnection the
|
||||||
|
SDU driver broadcasts a CHN_DISCONNECTED event.
|
||||||
- HAL: Modified the USB driver to have a separate USB_SUSPENDED state, this
|
- HAL: Modified the USB driver to have a separate USB_SUSPENDED state, this
|
||||||
allows the application to detect if the USB is communicating or if
|
allows the application to detect if the USB is communicating or if
|
||||||
it is disconnected or powered down.
|
it is disconnected or powered down.
|
||||||
|
|
|
@ -284,6 +284,12 @@ static void usb_event(USBDriver *usbp, usbevent_t event) {
|
||||||
chSysUnlockFromISR();
|
chSysUnlockFromISR();
|
||||||
return;
|
return;
|
||||||
case USB_EVENT_SUSPEND:
|
case USB_EVENT_SUSPEND:
|
||||||
|
chSysLockFromISR();
|
||||||
|
|
||||||
|
/* Disconnection event on suspend.*/
|
||||||
|
sduDisconnectI(&SDU2);
|
||||||
|
|
||||||
|
chSysUnlockFromISR();
|
||||||
return;
|
return;
|
||||||
case USB_EVENT_WAKEUP:
|
case USB_EVENT_WAKEUP:
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue