drivers/pn532_uart: flush uart input on error to resync uart port

This commit is contained in:
Romuald Conty 2012-05-10 19:37:55 +00:00
parent 896fa54ece
commit 851d035588

View file

@ -367,16 +367,15 @@ pn532_uart_receive (nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, i
return pn532_uart_ack (pnd);
}
if (pnd->last_error != 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
return pnd->last_error;
if (pnd->last_error < 0) {
goto error;
}
const uint8_t pn53x_preamble[3] = { 0x00, 0x00, 0xff };
if (0 != (memcmp (abtRxBuf, pn53x_preamble, 3))) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame preamble+start code mismatch");
pnd->last_error = NFC_EIO;
return pnd->last_error;
goto error;
}
if ((0x01 == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
@ -384,19 +383,20 @@ pn532_uart_receive (nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, i
uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 3, 0, timeout);
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Application level error detected");
pnd->last_error = NFC_EIO;
return pnd->last_error;
goto error;
} else if ((0xff == abtRxBuf[3]) && (0xff == abtRxBuf[4])) {
// Extended frame
pnd->last_error = uart_receive (DRIVER_DATA(pnd)->port, abtRxBuf, 3, 0, timeout);
if (pnd->last_error) return pnd->last_error;
if (pnd->last_error != 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
goto error;
}
// (abtRxBuf[0] << 8) + abtRxBuf[1] (LEN) include TFI + (CC+1)
len = (abtRxBuf[0] << 8) + abtRxBuf[1] - 2;
if (((abtRxBuf[0] + abtRxBuf[1] + abtRxBuf[2]) % 256) != 0) {
// TODO: Retry
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Length checksum mismatch");
pnd->last_error = NFC_EIO;
return pnd->last_error;
goto error;
}
} else {
// Normal frame
@ -404,7 +404,7 @@ pn532_uart_receive (nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, i
// TODO: Retry
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Length checksum mismatch");
pnd->last_error = NFC_EIO;
return pnd->last_error;
goto error;
}
// abtRxBuf[3] (LEN) include TFI + (CC+1)
@ -414,40 +414,40 @@ pn532_uart_receive (nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, i
if (len > szDataLen) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "Unable to receive data: buffer too small. (szDataLen: %zu, len: %zu)", szDataLen, len);
pnd->last_error = NFC_EIO;
return pnd->last_error;
goto error;
}
// TFI + PD0 (CC+1)
pnd->last_error = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 2, 0, timeout);
if (pnd->last_error != 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
return pnd->last_error;
goto error;
}
if (abtRxBuf[0] != 0xD5) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "TFI Mismatch");
pnd->last_error = NFC_EIO;
return pnd->last_error;
goto error;
}
if (abtRxBuf[1] != CHIP_DATA (pnd)->last_command + 1) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Command Code verification failed");
pnd->last_error = NFC_EIO;
return pnd->last_error;
goto error;
}
if (len) {
pnd->last_error = uart_receive (DRIVER_DATA (pnd)->port, pbtData, len, 0, timeout);
if (pnd->last_error != 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
return pnd->last_error;
goto error;
}
}
pnd->last_error = uart_receive (DRIVER_DATA (pnd)->port, abtRxBuf, 2, 0, timeout);
if (pnd->last_error != 0) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Unable to receive data. (RX)");
return pnd->last_error;
goto error;
}
uint8_t btDCS = (256 - 0xD5);
@ -459,16 +459,19 @@ pn532_uart_receive (nfc_device *pnd, uint8_t *pbtData, const size_t szDataLen, i
if (btDCS != abtRxBuf[0]) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Data checksum mismatch");
pnd->last_error = NFC_EIO;
return pnd->last_error;
goto error;
}
if (0x00 != abtRxBuf[1]) {
log_put (LOG_CATEGORY, NFC_PRIORITY_ERROR, "%s", "Frame postamble mismatch");
pnd->last_error = NFC_EIO;
return pnd->last_error;
goto error;
}
// The PN53x command is done and we successfully received the reply
return len;
error:
uart_flush_input (DRIVER_DATA (pnd)->port);
return pnd->last_error;
}
int