Fix pn532_uart driver.
This commit is contained in:
parent
eb90b92c12
commit
edba53c5da
4 changed files with 61 additions and 51 deletions
|
@ -107,11 +107,10 @@ serial_port uart_open(const char* pcPortName)
|
||||||
return sp;
|
return sp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void uart_set_speed(nfc_device_t* pnd, const uint32_t uiPortSpeed)
|
void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed)
|
||||||
{
|
{
|
||||||
serial_port sp = (serial_port)pnd->nds;
|
|
||||||
DBG("Serial port speed requested to be set to %d bauds.", uiPortSpeed);
|
DBG("Serial port speed requested to be set to %d bauds.", uiPortSpeed);
|
||||||
// Set port speed (Input and Output)
|
const serial_port_unix* spu = (serial_port_unix*)sp;
|
||||||
|
|
||||||
// Portability note: on some systems, B9600 != 9600 so we have to do
|
// Portability note: on some systems, B9600 != 9600 so we have to do
|
||||||
// uint32_t <=> speed_t associations by hand.
|
// uint32_t <=> speed_t associations by hand.
|
||||||
|
@ -142,18 +141,18 @@ void uart_set_speed(nfc_device_t* pnd, const uint32_t uiPortSpeed)
|
||||||
default:
|
default:
|
||||||
ERR("Unable to set serial port speed to %d bauds. Speed value must be one of those defined in termios(3).", uiPortSpeed);
|
ERR("Unable to set serial port speed to %d bauds. Speed value must be one of those defined in termios(3).", uiPortSpeed);
|
||||||
};
|
};
|
||||||
const serial_port_unix* spu = (serial_port_unix*)sp;
|
|
||||||
cfsetispeed((struct termios*)&spu->tiNew, stPortSpeed);
|
// Set port speed (Input and Output)
|
||||||
cfsetospeed((struct termios*)&spu->tiNew, stPortSpeed);
|
cfsetispeed((struct termios*)&(spu->tiNew), stPortSpeed);
|
||||||
if( tcsetattr(spu->fd, TCSADRAIN, &spu->tiNew) == -1)
|
cfsetospeed((struct termios*)&(spu->tiNew), stPortSpeed);
|
||||||
|
if( tcsetattr(spu->fd, TCSADRAIN, &(spu->tiNew)) == -1)
|
||||||
{
|
{
|
||||||
ERR("%s", "Unable to apply new speed settings.");
|
ERR("%s", "Unable to apply new speed settings.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t uart_get_speed(const nfc_device_t* pnd)
|
uint32_t uart_get_speed(serial_port sp)
|
||||||
{
|
{
|
||||||
serial_port sp = (serial_port)pnd->nds;
|
|
||||||
uint32_t uiPortSpeed = 0;
|
uint32_t uiPortSpeed = 0;
|
||||||
const serial_port_unix* spu = (serial_port_unix*)sp;
|
const serial_port_unix* spu = (serial_port_unix*)sp;
|
||||||
switch (cfgetispeed(&spu->tiNew))
|
switch (cfgetispeed(&spu->tiNew))
|
||||||
|
@ -194,13 +193,18 @@ void uart_close(const serial_port sp)
|
||||||
free(sp);
|
free(sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool uart_receive(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen)
|
/**
|
||||||
|
* @brief Receive data from UART and copy data to \a pbtRx
|
||||||
|
*
|
||||||
|
* @return 0 on success, otherwise driver error code
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
uart_receive(serial_port sp, byte_t* pbtRx, size_t* pszRxLen)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
int byteCount;
|
int byteCount;
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
serial_port sp = (serial_port)pnd->nds;
|
|
||||||
|
|
||||||
// Reset the output count
|
// Reset the output count
|
||||||
*pszRxLen = 0;
|
*pszRxLen = 0;
|
||||||
|
@ -215,8 +219,7 @@ bool uart_receive(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen)
|
||||||
// Read error
|
// Read error
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
DBG("%s", "RX error.");
|
DBG("%s", "RX error.");
|
||||||
pnd->iLastError = DEIO;
|
return DEIO;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read time-out
|
// Read time-out
|
||||||
|
@ -224,19 +227,17 @@ bool uart_receive(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen)
|
||||||
if (*pszRxLen == 0) {
|
if (*pszRxLen == 0) {
|
||||||
// Error, we received no data
|
// Error, we received no data
|
||||||
DBG("%s", "RX time-out, buffer empty.");
|
DBG("%s", "RX time-out, buffer empty.");
|
||||||
pnd->iLastError = DETIMEOUT;
|
return DETIMEOUT;
|
||||||
return false;
|
|
||||||
} else {
|
} else {
|
||||||
// We received some data, but nothing more is available
|
// We received some data, but nothing more is available
|
||||||
return true;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve the count of the incoming bytes
|
// Retrieve the count of the incoming bytes
|
||||||
res = ioctl(((serial_port_unix*)sp)->fd, FIONREAD, &byteCount);
|
res = ioctl(((serial_port_unix*)sp)->fd, FIONREAD, &byteCount);
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
pnd->iLastError = DEIO;
|
return DEIO;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// There is something available, read the data
|
// There is something available, read the data
|
||||||
|
@ -244,24 +245,28 @@ bool uart_receive(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen)
|
||||||
|
|
||||||
// Stop if the OS has some troubles reading the data
|
// Stop if the OS has some troubles reading the data
|
||||||
if (res <= 0) {
|
if (res <= 0) {
|
||||||
pnd->iLastError = DEIO;
|
return DEIO;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*pszRxLen += res;
|
*pszRxLen += res;
|
||||||
|
|
||||||
} while (byteCount);
|
} while (byteCount);
|
||||||
|
|
||||||
return true;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool uart_send(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen)
|
/**
|
||||||
|
* @brief Send \a pbtTx content to UART
|
||||||
|
*
|
||||||
|
* @return 0 on success, otherwise a driver error is returned
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
uart_send(serial_port sp, const byte_t* pbtTx, const size_t szTxLen)
|
||||||
{
|
{
|
||||||
int32_t res;
|
int32_t res;
|
||||||
size_t szPos = 0;
|
size_t szPos = 0;
|
||||||
fd_set rfds;
|
fd_set rfds;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
serial_port sp = (serial_port)pnd->nds;
|
|
||||||
|
|
||||||
while (szPos < szTxLen)
|
while (szPos < szTxLen)
|
||||||
{
|
{
|
||||||
|
@ -274,15 +279,13 @@ bool uart_send(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen)
|
||||||
// Write error
|
// Write error
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
DBG("%s", "TX error.");
|
DBG("%s", "TX error.");
|
||||||
pnd->iLastError = DEIO;
|
return DEIO;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write time-out
|
// Write time-out
|
||||||
if (res == 0) {
|
if (res == 0) {
|
||||||
DBG("%s", "TX time-out.");
|
DBG("%s", "TX time-out.");
|
||||||
pnd->iLastError = DETIMEOUT;
|
return DETIMEOUT;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send away the bytes
|
// Send away the bytes
|
||||||
|
@ -290,13 +293,12 @@ bool uart_send(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen)
|
||||||
|
|
||||||
// Stop if the OS has some troubles sending the data
|
// Stop if the OS has some troubles sending the data
|
||||||
if (res <= 0) {
|
if (res <= 0) {
|
||||||
pnd->iLastError = DEIO;
|
return DEIO;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
szPos += res;
|
szPos += res;
|
||||||
}
|
}
|
||||||
return true;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -81,12 +81,11 @@ typedef void* serial_port;
|
||||||
serial_port uart_open(const char* pcPortName);
|
serial_port uart_open(const char* pcPortName);
|
||||||
void uart_close(const serial_port sp);
|
void uart_close(const serial_port sp);
|
||||||
|
|
||||||
void uart_set_speed(nfc_device_t* pnd, const uint32_t uiPortSpeed);
|
void uart_set_speed(serial_port sp, const uint32_t uiPortSpeed);
|
||||||
uint32_t uart_get_speed(const nfc_device_t* pnd);
|
uint32_t uart_get_speed(const serial_port sp);
|
||||||
|
|
||||||
bool uart_receive(nfc_device_t* pnd, byte_t* pbtRx, size_t* pszRxLen);
|
int uart_receive(serial_port sp, byte_t* pbtRx, size_t* pszRxLen);
|
||||||
bool uart_send(nfc_device_t* pnd, const byte_t* pbtTx, const size_t szTxLen);
|
int uart_send(serial_port sp, const byte_t* pbtTx, const size_t szTxLen);
|
||||||
|
|
||||||
#endif // __NFC_BUS_UART_H__
|
#endif // __NFC_BUS_UART_H__
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -69,9 +69,10 @@ const byte_t pncmd_target_get_status [ 2] = { 0xD4,0x8A };
|
||||||
static const byte_t pn53x_ack_frame[] = { 0x00,0x00,0xff,0x00,0xff,0x00 };
|
static const byte_t pn53x_ack_frame[] = { 0x00,0x00,0xff,0x00,0xff,0x00 };
|
||||||
static const byte_t pn53x_nack_frame[] = { 0x00,0x00,0xff,0xff,0x00,0x00 };
|
static const byte_t pn53x_nack_frame[] = { 0x00,0x00,0xff,0xff,0x00,0x00 };
|
||||||
|
|
||||||
|
// XXX: Is this function correctly named ?
|
||||||
bool pn53x_transceive_callback(nfc_device_t* pnd, const byte_t *pbtRxFrame, const size_t szRxFrameLen)
|
bool pn53x_transceive_callback(nfc_device_t* pnd, const byte_t *pbtRxFrame, const size_t szRxFrameLen)
|
||||||
{
|
{
|
||||||
if (szRxFrameLen == sizeof (pn53x_ack_frame)) {
|
if (szRxFrameLen >= sizeof (pn53x_ack_frame)) {
|
||||||
if (0 == memcmp (pbtRxFrame, pn53x_ack_frame, sizeof (pn53x_ack_frame))) {
|
if (0 == memcmp (pbtRxFrame, pn53x_ack_frame, sizeof (pn53x_ack_frame))) {
|
||||||
DBG("%s", "PN53x ACKed");
|
DBG("%s", "PN53x ACKed");
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -100,7 +100,7 @@ pn532_uart_list_devices(nfc_device_desc_t pnddDevices[], size_t szDevices, size_
|
||||||
// PN532 could be powered down, we need to wake it up before line testing.
|
// PN532 could be powered down, we need to wake it up before line testing.
|
||||||
pn532_uart_wakeup((nfc_device_spec_t)sp);
|
pn532_uart_wakeup((nfc_device_spec_t)sp);
|
||||||
// Check communication using "Diagnose" command, with "Comunication test" (0x00)
|
// Check communication using "Diagnose" command, with "Comunication test" (0x00)
|
||||||
if(!pn532_uart_check_communication((nfc_device_spec_t)sp), &bComOk)
|
if(!pn532_uart_check_communication((nfc_device_spec_t)sp, &bComOk))
|
||||||
return false;
|
return false;
|
||||||
if (!bComOk)
|
if (!bComOk)
|
||||||
continue;
|
continue;
|
||||||
|
@ -200,16 +200,19 @@ bool pn532_uart_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRINT_HEX("TX", abtTxBuf,szTxLen+7);
|
PRINT_HEX("TX", abtTxBuf,szTxLen+7);
|
||||||
#endif
|
#endif
|
||||||
if (!uart_send((serial_port)pnd->nds,abtTxBuf,szTxLen+7)) {
|
int res;
|
||||||
|
res = uart_send((serial_port)pnd->nds,abtTxBuf,szTxLen+7);
|
||||||
|
if(res != 0) {
|
||||||
ERR("%s", "Unable to transmit data. (TX)");
|
ERR("%s", "Unable to transmit data. (TX)");
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = res;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
szRxBufLen = 6;
|
szRxBufLen = 6;
|
||||||
if (!uart_receive((serial_port)pnd->nds,abtRxBuf,&szRxBufLen)) {
|
res = uart_receive((serial_port)pnd->nds,abtRxBuf,&szRxBufLen);
|
||||||
|
if (res != 0) {
|
||||||
ERR("%s", "Unable to receive data. (RX)");
|
ERR("%s", "Unable to receive data. (RX)");
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = res;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -217,18 +220,22 @@ bool pn532_uart_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t
|
||||||
PRINT_HEX("RX", abtRxBuf,szRxBufLen);
|
PRINT_HEX("RX", abtRxBuf,szRxBufLen);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// WARN: UART is a per byte reception, so you usually receive ACK and next frame the same time
|
||||||
if (!pn53x_transceive_callback(pnd, abtRxBuf, szRxBufLen))
|
if (!pn53x_transceive_callback(pnd, abtRxBuf, szRxBufLen))
|
||||||
return false;
|
return false;
|
||||||
|
szRxBufLen -= sizeof(ack_frame);
|
||||||
|
memmove(abtRxBuf, abtRxBuf+sizeof(ack_frame), szRxBufLen);
|
||||||
|
|
||||||
|
if (szRxBufLen == 0) {
|
||||||
szRxBufLen = BUFFER_LENGTH;
|
szRxBufLen = BUFFER_LENGTH;
|
||||||
|
do {
|
||||||
while (!uart_receive((serial_port)pnd->nds,abtRxBuf,&szRxBufLen)) {
|
|
||||||
delay_ms(10);
|
delay_ms(10);
|
||||||
}
|
res = uart_receive((serial_port)pnd->nds,abtRxBuf,&szRxBufLen);
|
||||||
|
} while (res != 0 );
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRINT_HEX("RX", abtRxBuf,szRxBufLen);
|
PRINT_HEX("RX", abtRxBuf,szRxBufLen);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// When the answer should be ignored, just return a successful result
|
// When the answer should be ignored, just return a successful result
|
||||||
if(pbtRx == NULL || pszRxLen == NULL) return true;
|
if(pbtRx == NULL || pszRxLen == NULL) return true;
|
||||||
|
@ -242,9 +249,10 @@ bool pn532_uart_transceive(nfc_device_t* pnd, const byte_t* pbtTx, const size_t
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRINT_HEX("TX", ack_frame,6);
|
PRINT_HEX("TX", ack_frame,6);
|
||||||
#endif
|
#endif
|
||||||
if (!uart_send((serial_port)pnd->nds,ack_frame,6)) {
|
res = uart_send((serial_port)pnd->nds,ack_frame,6);
|
||||||
|
if (res != 0) {
|
||||||
ERR("%s", "Unable to transmit data. (TX)");
|
ERR("%s", "Unable to transmit data. (TX)");
|
||||||
pnd->iLastError = DEIO;
|
pnd->iLastError = res;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,7 +276,7 @@ pn532_uart_wakeup(const nfc_device_spec_t nds)
|
||||||
PRINT_HEX("TX", pncmd_pn532c106_wakeup_preamble,sizeof(pncmd_pn532c106_wakeup_preamble));
|
PRINT_HEX("TX", pncmd_pn532c106_wakeup_preamble,sizeof(pncmd_pn532c106_wakeup_preamble));
|
||||||
#endif
|
#endif
|
||||||
uart_send((serial_port)nds, pncmd_pn532c106_wakeup_preamble, sizeof(pncmd_pn532c106_wakeup_preamble));
|
uart_send((serial_port)nds, pncmd_pn532c106_wakeup_preamble, sizeof(pncmd_pn532c106_wakeup_preamble));
|
||||||
if(uart_receive((serial_port)nds,abtRx,&szRxLen)) {
|
if(0 == uart_receive((serial_port)nds,abtRx,&szRxLen)) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRINT_HEX("RX", abtRx,szRxLen);
|
PRINT_HEX("RX", abtRx,szRxLen);
|
||||||
#endif
|
#endif
|
||||||
|
@ -290,10 +298,10 @@ pn532_uart_check_communication(const nfc_device_spec_t nds, bool* success)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
PRINT_HEX("TX", pncmd_communication_test,sizeof(pncmd_communication_test));
|
PRINT_HEX("TX", pncmd_communication_test,sizeof(pncmd_communication_test));
|
||||||
#endif
|
#endif
|
||||||
if (!uart_send((serial_port)nds, pncmd_communication_test, sizeof(pncmd_communication_test)))
|
if (0 != uart_send((serial_port)nds, pncmd_communication_test, sizeof(pncmd_communication_test)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(!uart_receive((serial_port)nds,abtRx,&szRxLen)) {
|
if (0 != uart_receive((serial_port)nds,abtRx,&szRxLen)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
Loading…
Add table
Reference in a new issue