drivers/pn53x_usb: make PN53x usb connection more stable:

- move well-know USB problem hack into pn53x_usb_bulk_write()
 - put NACK hack to handle PN533 direct reply case
This commit is contained in:
Romuald Conty 2011-05-17 10:41:26 +00:00
parent 6b5a582386
commit da6add3534

View file

@ -94,7 +94,12 @@ int
pn53x_usb_bulk_write (struct pn53x_usb_data *data, byte_t abtTx[], const size_t szTx)
{
PRINT_HEX ("TX", abtTx, szTx);
return usb_bulk_write (data->pudh, data->uiEndPointOut, (char *) abtTx, szTx, USB_TIMEOUT);
int res = usb_bulk_write (data->pudh, data->uiEndPointOut, (char *) abtTx, szTx, USB_TIMEOUT);
// HACK This little hack is a well know problem of USB, see http://www.libusb.org/ticket/6 for more details
if ((res % data->uiMaxPacketSize) == 0) {
usb_bulk_write (data->pudh, data->uiEndPointOut, "\0", 0, USB_TIMEOUT);
}
return res;
}
struct pn53x_usb_supported_device {
@ -126,6 +131,7 @@ pn53x_usb_get_device_model (uint16_t vendor_id, uint16_t product_id)
// TODO Move this HACK1 into an upper level in order to benefit to other devices that use PN53x
static const byte_t ack_frame[] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
static const byte_t nack_frame[] = { 0x00, 0x00, 0xff, 0xff, 0x00, 0x00 };
int pn53x_usb_ack (nfc_device_t * pnd);
@ -372,10 +378,6 @@ pn53x_usb_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData)
pn53x_build_frame (abtFrame, &szFrame, pbtData, szData);
int res = pn53x_usb_bulk_write (DRIVER_DATA (pnd), abtFrame, szFrame);
// HACK This little hack is a well know problem of USB, see http://www.libusb.org/ticket/6 for more details
if ((res % DRIVER_DATA (pnd)->uiMaxPacketSize) == 0) {
usb_bulk_write (DRIVER_DATA (pnd)->pudh, DRIVER_DATA(pnd)->uiEndPointOut, "\0", 0, USB_TIMEOUT);
}
if (res < 0) {
DBG ("usb_bulk_write failed with error %d", res);
@ -396,8 +398,21 @@ pn53x_usb_send (nfc_device_t * pnd, const byte_t * pbtData, const size_t szData)
if (pn53x_check_ack_frame (pnd, abtRxBuf, res)) {
// The PN53x is running the sent command
} else {
// For some reasons (eg. send another command while a previous one is
// running), the PN533 sometimes directly replies the response packet
// instead of ACK frame, so we send a NACK frame to force PN533 to resend
// response packet. With this hack, the nextly executed function (ie.
// pn53x_usb_receive()) will be able to retreive the correct response
// packet.
int res = pn53x_usb_bulk_write (DRIVER_DATA (pnd), (byte_t *)nack_frame, sizeof(nack_frame));
if (res < 0) {
DBG ("usb_bulk_write failed with error %d", res);
pnd->iLastError = DEIO;
// try to interrupt current device state
pn53x_usb_ack(pnd);
return false;
}
}
return true;
}