From 047b7d20068f4a25fe7caeafcb46868bb910362c Mon Sep 17 00:00:00 2001 From: Romuald Conty Date: Mon, 21 Sep 2009 14:57:55 +0000 Subject: [PATCH] Add rs232_get_speed function. (Thanks to Zuck) Add missing RS232 functions for Windows. Not yet tested (Thanks to Zuck) Add comment about timing problem using ARYGON readers. --- src/dev_arygon.c | 17 +++++---- src/rs232.c | 92 ++++++++++++++++++++++++++++++++++++++++-------- src/rs232.h | 1 + 3 files changed, 88 insertions(+), 22 deletions(-) diff --git a/src/dev_arygon.c b/src/dev_arygon.c index 0779fae..92b0d25 100644 --- a/src/dev_arygon.c +++ b/src/dev_arygon.c @@ -168,17 +168,20 @@ bool dev_arygon_transceive(const dev_spec ds, const byte_t* pbtTx, const uint32_ return false; } - /** @todo Find why this delay are needed. (in PN532 datasheet, but I (Romuald) haven't it...) */ - /** @note PN532 need 20ms between sending and receiving frame. No information regarding this in ARYGON datasheet... */ - /** @note It seems to be a required delay to able to send from host to device, plus the device computation then device respond transmission */ + /** @note PN532 (at 115200 bauds) need 20ms between sending and receiving frame. No information regarding this in ARYGON datasheet... + * It seems to be a required delay to able to send from host to device, plus the device computation then device respond transmission + */ delay_ms(20); - /** @note PN532 need 30ms more to be stable (report correctly present tag, at each try: 20ms seems to be enought for one shot...) */ + /** @note PN532 (at 115200 bauds) need 30ms more to be stable (report correctly present tag, at each try: 20ms seems to be enought for one shot...) + * PN532 seems to work correctly with 50ms at 115200 bauds. + */ delay_ms(30); - /** @note PN532 seems to work correctly with 50ms at 115200 bauds */ - /** @note PN532 seems to work correctly with 70ms at 9600 bauds */ - delay_ms(20); + /** @note Unfortunately, adding delay is not enought for ARYGON readers which are equipped with an ARYGON µC + PN532 running at 9600 bauds. + * There are too many timing problem to solve them by adding more and more delay. + * For more information, see Issue 23 on development site : http://code.google.com/p/libnfc/issues/detail?id=23 + */ if (!rs232_receive((serial_port)ds,abtRxBuf,&uiRxBufLen)) { ERR("Unable to receive data. (RX)"); diff --git a/src/rs232.c b/src/rs232.c index edf36ad..c829394 100644 --- a/src/rs232.c +++ b/src/rs232.c @@ -50,29 +50,29 @@ struct timeval tv = { serial_port rs232_open(const char* pcPortName) { serial_port_unix* sp = malloc(sizeof(serial_port_unix)); - + if (sp == 0) return INVALID_SERIAL_PORT; - + sp->fd = open(pcPortName, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK); if(sp->fd == -1) { rs232_close(sp); return INVALID_SERIAL_PORT; } - + if(tcgetattr(sp->fd,&sp->tiOld) == -1) { rs232_close(sp); return INVALID_SERIAL_PORT; } - + // Make sure the port is not claimed already if (sp->tiOld.c_iflag & CCLAIMED) { rs232_close(sp); return CLAIMED_SERIAL_PORT; } - + // Copy the old terminal info struct sp->tiNew = sp->tiOld; @@ -83,6 +83,7 @@ serial_port rs232_open(const char* pcPortName) sp->tiNew.c_cc[VMIN] = 0; // block until n bytes are received sp->tiNew.c_cc[VTIME] = 0; // block until a timer expires (n * 100 mSec.) + if(tcsetattr(sp->fd,TCSANOW,&sp->tiNew) == -1) { rs232_close(sp); @@ -97,34 +98,59 @@ void rs232_set_speed(const serial_port sp, const uint32_t uiPortSpeed) { DBG("Serial port speed requested to be set to %d bauds.", uiPortSpeed); // Set port speed (Input and Output) - speed_t portSpeed = B9600; + speed_t stPortSpeed = B9600; switch(uiPortSpeed) { - case 9600: portSpeed = B9600; + case 9600: stPortSpeed = B9600; break; - case 19200: portSpeed = B19200; + case 19200: stPortSpeed = B19200; break; - case 38400: portSpeed = B38400; + case 38400: stPortSpeed = B38400; break; - case 57600: portSpeed = B57600; + case 57600: stPortSpeed = B57600; break; - case 115200: portSpeed = B115200; + case 115200: stPortSpeed = B115200; break; - case 230400: portSpeed = B230400; + case 230400: stPortSpeed = B230400; break; - case 460800: portSpeed = B460800; + case 460800: stPortSpeed = B460800; break; default: ERR("Unable to set serial port speed to %d bauds. Speed value must be one of these constants: 9600 (default), 19200, 38400, 57600, 115200, 230400 or 460800.", uiPortSpeed); }; const serial_port_unix* spu = (serial_port_unix*)sp; - cfsetispeed(&spu->tiNew, portSpeed); - cfsetospeed(&spu->tiNew, portSpeed); + cfsetispeed(&spu->tiNew, stPortSpeed); + cfsetospeed(&spu->tiNew, stPortSpeed); if( tcsetattr(spu->fd, TCSADRAIN, &spu->tiNew) == -1) { ERR("Unable to apply new speed settings."); } } +uint32_t rs232_get_speed(const serial_port sp) +{ + uint32_t uiPortSpeed = 0; + const serial_port_unix* spu = (serial_port_unix*)sp; + switch (cfgetispeed(&spu->tiNew)) + { + case B9600: uiPortSpeed = 9600; + break; + case B19200: uiPortSpeed = 19200; + break; + case B38400: uiPortSpeed = 38400; + break; + case B57600: uiPortSpeed = 57600; + break; + case B115200: uiPortSpeed = 115200; + break; + case B230400: uiPortSpeed = 230400; + break; + case B460800: uiPortSpeed = 460800; + break; + } + + return uiPortSpeed; +} + void rs232_close(const serial_port sp) { tcsetattr(((serial_port_unix*)sp)->fd,TCSANOW,&((serial_port_unix*)sp)->tiOld); @@ -240,6 +266,8 @@ serial_port rs232_open(const char* pcPortName) return INVALID_SERIAL_PORT; } + PurgeComm(sp->hPort, PURGE_RXABORT | PURGE_RXCLEAR); + return sp; } @@ -249,6 +277,40 @@ void rs232_close(const serial_port sp) free(sp); } +void rs232_set_speed(const serial_port sp, const uint32_t uiPortSpeed) +{ + DBG("Serial port speed requested to be set to %d bauds.", uiPortSpeed); + // Set port speed (Input and Output) + switch(uiPortSpeed) { + case 9600: + case 19200: + case 38400: + case 57600: + case 115200: + case 230400: + case 460800: + break; + default: + ERR("Unable to set serial port speed to %d bauds. Speed value must be one of these constants: 9600 (default), 19200, 38400, 57600, 115200, 230400 or 460800.", uiPortSpeed); + }; + + serial_port_windows* spw = (serial_port_windows*)sp; + spw->dcb.BaudRate = uiPortSpeed; + if (!SetCommState(spw->hPort, &spw->dcb)) + { + ERR("Unable to apply new speed settings."); + } +} + +uint32_t rs232_get_speed(const serial_port sp) +{ + const serial_port_windows* spw = (serial_port_windows*)sp; + if (!GetCommState(spw->hPort, &spw->dcb)) + return spw->dcb.BaudRate; + + return 0; +} + bool rs232_cts(const serial_port sp) { DWORD dwStatus; diff --git a/src/rs232.h b/src/rs232.h index 690462c..f95e211 100644 --- a/src/rs232.h +++ b/src/rs232.h @@ -50,6 +50,7 @@ serial_port rs232_open(const char* pcPortName); void rs232_close(const serial_port sp); void rs232_set_speed(const serial_port sp, uint32_t uiPortSpeed); +uint32_t rs232_get_speed(const serial_port sp); bool rs232_cts(const serial_port sp);