From 93c512316922dde3edd28eb8388b7abcdf0174ec Mon Sep 17 00:00:00 2001 From: Kevin Townsend Date: Tue, 7 Feb 2012 12:51:43 +0100 Subject: [PATCH] I2C and LCD bug fixes --- ChangeLog.txt | 12 +- .../LPC1343 Workspace.workspace.session | 30 ++--- build/crossworks/LPC1343_CodeBase.hzp | 12 +- build/crossworks/LPC1343_CodeBase.hzs | 20 +++- core/i2c/i2c.c | 34 +++++- core/i2c/i2c.h | 22 +++- drivers/lcd/tft/hw/ILI9328.h | 33 +++--- drivers/lcd/tft/touchscreen.c | 47 ++++++-- drivers/lcd/tft/touchscreen.h | 9 +- drivers/sensors/pn532/pn532.h | 3 +- drivers/sensors/pn532/pn532_bus.h | 5 +- sysinit.c | 13 +++ .../sensors/pn532/ISO14443A_ID/main.c | 110 +++++++++++------- 13 files changed, 231 insertions(+), 119 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 02456ff..52bd28a 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1,8 +1,16 @@ v0.9.8 - Ongoing ================ +- updated touchscreen.h to be a bit clearer during + calibration, though it can still be much better + organised +- Had to add "__asm volatile("nop");" after pin writes + in the ILI9328 driver since some LCDs couldn't + keep up with the high-speed writes with bit-banding +- Fixed I2C clock duty cycle registers +- Changed I2C buffer size from 32 to 64 bytes (i2c.h) - Added CFG_BRD_LPC1343_OLIMEX_P to board selection in projectconfig.h (courtesy PHK) -- Added SSD1331_COLORORDER_RGB flasg to SSD1331.h to +- Added SSD1331_COLORORDER_RGB flag to SSD1331.h to select between RGB and BGR color order - Added 128x32 support to ssd1306.c and rewrote initialize sequence for 128x32 and 128x64 displays @@ -19,7 +27,7 @@ v0.9.8 - Ongoing - Changed CodeLite project files to support real debugging with a Segger J-Link and GDB Server. - Fixed issue with USB CDC instantiation for - FreeBSD + FreeBSD (courtesy PHK) - Added experimental SSD1351 OLED driver to /drivers/lcd/tft/hw diff --git a/build/codelite/LPC1343 Workspace.workspace.session b/build/codelite/LPC1343 Workspace.workspace.session index 7b19ea7..89b677c 100644 --- a/build/codelite/LPC1343 Workspace.workspace.session +++ b/build/codelite/LPC1343 Workspace.workspace.session @@ -1,34 +1,24 @@ - + - - + + + + + + + + - + - - - - - - - - - - - - - - - - diff --git a/build/crossworks/LPC1343_CodeBase.hzp b/build/crossworks/LPC1343_CodeBase.hzp index 5a6c270..b5c6b47 100644 --- a/build/crossworks/LPC1343_CodeBase.hzp +++ b/build/crossworks/LPC1343_CodeBase.hzp @@ -1,7 +1,7 @@ - + @@ -177,7 +177,7 @@ - + @@ -216,13 +216,13 @@ - - + + - - + + diff --git a/build/crossworks/LPC1343_CodeBase.hzs b/build/crossworks/LPC1343_CodeBase.hzs index b11be97..f56c47e 100644 --- a/build/crossworks/LPC1343_CodeBase.hzs +++ b/build/crossworks/LPC1343_CodeBase.hzs @@ -1,7 +1,16 @@ - + + + + + + + + + + @@ -24,10 +33,9 @@ - - - - + + + @@ -63,7 +71,7 @@ - + diff --git a/core/i2c/i2c.c b/core/i2c/i2c.c index f9df690..2db915e 100644 --- a/core/i2c/i2c.c +++ b/core/i2c/i2c.c @@ -274,7 +274,7 @@ static uint32_t I2CStop( void ) *****************************************************************************/ uint32_t i2cInit( uint32_t I2cMode ) { - SCB_PRESETCTRL |= (0x1<<1); + SCB_PRESETCTRL |= (0x1<<1); // Enable I2C clock SCB_SYSAHBCLKCTRL |= (SCB_SYSAHBCLKCTRL_I2C); @@ -347,6 +347,38 @@ uint32_t i2cEngine( void ) return ( I2CMasterState ); } +/***************************************************************************** +** Function name: i2cSendGeneralCall +** +** Descriptions: Sends a request to the general call address (0x00) +** which should detect if there are any devices on the +** i2c bus. For more information see: +** http://www.i2c-bus.org/addressing/general-call-address/ +** +** parameters: None +** Returned value: Any of the I2CSTATE_... values. See i2c.h +** +*****************************************************************************/ +uint32_t i2cSendGeneralCall(void) +{ + uint32_t i2cState; + + // Clear write buffers + uint32_t i; + for ( i = 0; i < I2C_BUFSIZE; i++ ) + { + I2CMasterBuffer[i] = 0x00; + } + + // Send the specified bytes + I2CWriteLength = 1; + I2CReadLength = 0; + I2CMasterBuffer[0] = I2C_GENERALCALL; + i2cState = i2cEngine(); + + return i2cState; +} + /****************************************************************************** ** End Of File ******************************************************************************/ diff --git a/core/i2c/i2c.h b/core/i2c/i2c.h index 2064351..ff1e224 100644 --- a/core/i2c/i2c.h +++ b/core/i2c/i2c.h @@ -39,7 +39,7 @@ #define FAST_MODE_PLUS 0 -#define I2C_BUFSIZE 32 +#define I2C_BUFSIZE 64 #define MAX_TIMEOUT 0x00FFFFFF #define I2CMASTER 0x01 @@ -50,6 +50,8 @@ #define RD_BIT 0x01 +#define I2C_GENERALCALL 0x00 /* General Call Address (to 'ping' I2C bus for devices) */ + #define I2CONSET_I2EN 0x00000040 /* I2C Control Set Register */ #define I2CONSET_AA 0x00000004 #define I2CONSET_SI 0x00000008 @@ -63,11 +65,20 @@ #define I2DAT_I2C 0x00000000 /* I2C Data Reg */ #define I2ADR_I2C 0x00000000 /* I2C Slave Address Reg */ -#define I2SCLH_SCLH 120 /* I2C SCL Duty Cycle High Reg */ -#define I2SCLL_SCLL 120 /* I2C SCL Duty Cycle Low Reg */ -#define I2SCLH_HS_SCLH 0x00000020 /* Fast Plus I2C SCL Duty Cycle High Reg */ -#define I2SCLL_HS_SCLL 0x00000020 /* Fast Plus I2C SCL Duty Cycle Low Reg */ +/* SCLH and SCLL = I2C PCLK High/Low cycles for I2C clock and + determine the data rate/duty cycle for I2C: + + I2CBitFrequency = I2CPCLK / (I2CSCLH + I2CSCLL) + + Standard Mode (100KHz) = CFG_CPU_CCLK / 200000 + Fast Mode (400KHz) = CFG_CPU_CCLK / 800000 + Fast- Mode Plus (1MHz) = CFG_CPU_CCLK / 2000000 */ + +#define I2SCLH_SCLH CFG_CPU_CCLK / 800000 /* Standard Mode I2C SCL Duty Cycle High (400KHz) */ +#define I2SCLL_SCLL CFG_CPU_CCLK / 800000 /* Fast Mode I2C SCL Duty Cycle Low (400KHz) */ +#define I2SCLH_HS_SCLH CFG_CPU_CCLK / 2000000 /* Fast Plus I2C SCL Duty Cycle High Reg */ +#define I2SCLL_HS_SCLL CFG_CPU_CCLK / 2000000 /* Fast Plus I2C SCL Duty Cycle Low Reg */ extern volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE]; extern volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE]; @@ -76,6 +87,7 @@ extern volatile uint32_t I2CReadLength, I2CWriteLength; extern void I2C_IRQHandler( void ); extern uint32_t i2cInit( uint32_t I2cMode ); extern uint32_t i2cEngine( void ); +uint32_t i2cSendGeneralCall( void ); #endif /* end __I2C_H */ /**************************************************************************** diff --git a/drivers/lcd/tft/hw/ILI9328.h b/drivers/lcd/tft/hw/ILI9328.h index 82cedb6..7a04249 100644 --- a/drivers/lcd/tft/hw/ILI9328.h +++ b/drivers/lcd/tft/hw/ILI9328.h @@ -108,25 +108,26 @@ #define ILI9328_GPIO2DATA_SETOUTPUT GPIO_GPIO2DIR |= ILI9328_DATA_MASK // Macros for control line state -#define CLR_CD ILI9328_GPIO1DATA_CD = (0) -#define SET_CD ILI9328_GPIO1DATA_CD = (1 << ILI9328_CD_PIN) -#define CLR_CS ILI9328_GPIO1DATA_CS = (0) -#define SET_CS ILI9328_GPIO1DATA_CS = (1 << ILI9328_CS_PIN) -#define CLR_WR ILI9328_GPIO1DATA_WR = (0) -#define SET_WR ILI9328_GPIO1DATA_WR = (1 << ILI9328_WR_PIN) -#define CLR_RD ILI9328_GPIO1DATA_RD = (0) -#define SET_RD ILI9328_GPIO1DATA_RD = (1 << ILI9328_RD_PIN) -#define CLR_RESET ILI9328_GPIO3DATA_RES = (0) -#define SET_RESET ILI9328_GPIO3DATA_RES = (1 << ILI9328_RES_PIN) +// NOPs required since the bit-banding is too fast for some ILI9328s to handle :( +#define CLR_CD ILI9328_GPIO1DATA_CD = (0); __asm volatile("nop"); +#define SET_CD ILI9328_GPIO1DATA_CD = (1 << ILI9328_CD_PIN); __asm volatile("nop"); +#define CLR_CS ILI9328_GPIO1DATA_CS = (0); __asm volatile("nop"); +#define SET_CS ILI9328_GPIO1DATA_CS = (1 << ILI9328_CS_PIN); __asm volatile("nop"); +#define CLR_WR ILI9328_GPIO1DATA_WR = (0); __asm volatile("nop"); +#define SET_WR ILI9328_GPIO1DATA_WR = (1 << ILI9328_WR_PIN); __asm volatile("nop"); +#define CLR_RD ILI9328_GPIO1DATA_RD = (0); __asm volatile("nop"); +#define SET_RD ILI9328_GPIO1DATA_RD = (1 << ILI9328_RD_PIN); __asm volatile("nop"); +#define CLR_RESET ILI9328_GPIO3DATA_RES = (0); __asm volatile("nop"); +#define SET_RESET ILI9328_GPIO3DATA_RES = (1 << ILI9328_RES_PIN); __asm volatile("nop"); // These 'combined' macros are defined to improve code performance by // reducing the number of instructions in heavily used functions -#define CLR_CS_CD ILI9328_GPIO1DATA_CS_CD = (0); -#define SET_RD_WR ILI9328_GPIO1DATA_RD_WR = (ILI9328_RD_WR_PINS); -#define SET_WR_CS ILI9328_GPIO1DATA_WR_CS = (ILI9328_WR_CS_PINS); -#define SET_CD_RD_WR ILI9328_GPIO1DATA_CD_RD_WR = (ILI9328_CD_RD_WR_PINS); -#define CLR_CS_CD_SET_RD_WR ILI9328_GPIO1DATA_CS_CD_RD_WR = (ILI9328_RD_WR_PINS); -#define CLR_CS_SET_CD_RD_WR ILI9328_GPIO1DATA_CS_CD_RD_WR = (ILI9328_CD_RD_WR_PINS); +#define CLR_CS_CD ILI9328_GPIO1DATA_CS_CD = (0); __asm volatile("nop"); +#define SET_RD_WR ILI9328_GPIO1DATA_RD_WR = (ILI9328_RD_WR_PINS); __asm volatile("nop"); +#define SET_WR_CS ILI9328_GPIO1DATA_WR_CS = (ILI9328_WR_CS_PINS); __asm volatile("nop"); +#define SET_CD_RD_WR ILI9328_GPIO1DATA_CD_RD_WR = (ILI9328_CD_RD_WR_PINS); __asm volatile("nop"); +#define CLR_CS_CD_SET_RD_WR ILI9328_GPIO1DATA_CS_CD_RD_WR = (ILI9328_RD_WR_PINS); __asm volatile("nop"); +#define CLR_CS_SET_CD_RD_WR ILI9328_GPIO1DATA_CS_CD_RD_WR = (ILI9328_CD_RD_WR_PINS); __asm volatile("nop"); enum { diff --git a/drivers/lcd/tft/touchscreen.c b/drivers/lcd/tft/touchscreen.c index 4d4a2cd..bb7371a 100644 --- a/drivers/lcd/tft/touchscreen.c +++ b/drivers/lcd/tft/touchscreen.c @@ -194,7 +194,8 @@ tsTouchData_t tsRenderCalibrationScreen(uint16_t x, uint16_t y, uint16_t radius) bool valid = false; while (!valid) { - error = tsRead(&data); + // Set calibration flag for ts read + error = tsRead(&data, true); if (!error && data.valid) { valid = true; @@ -283,7 +284,7 @@ int setCalibrationMatrix( tsPoint_t * displayPtr, tsPoint_t * screenPtr, tsMatri /**************************************************************************/ int getDisplayPoint( tsPoint_t * displayPtr, tsPoint_t * screenPtr, tsMatrix_t * matrixPtr ) { - int retValue = 0 ; + int retValue = TS_ERROR_NONE ; if( matrixPtr->Divider != 0 ) { @@ -299,7 +300,9 @@ int getDisplayPoint( tsPoint_t * displayPtr, tsPoint_t * screenPtr, tsMatrix_t * } else { - retValue = -1 ; + // ToDo: Default values required or you can never read LCD position! + // return TS_ERROR_NOTCALIBRATED; + return -1; } // Adjust value if the screen is in landscape mode @@ -350,14 +353,25 @@ void tsInit(void) _tsMatrix.Fn = eepromReadS32(CFG_EEPROM_TOUCHSCREEN_CAL_FN); _tsMatrix.Divider = eepromReadS32(CFG_EEPROM_TOUCHSCREEN_CAL_DIVIDER); } + else + { + // You may want to run the touch screen calibration sequence + // here since the ts has apparently never been calibrated! + // tsCalibrate(); + } } /**************************************************************************/ /*! @brief Reads the current X, Y and Z co-ordinates of the touch screen + + @param[in] calibrating + Set to 1 if the read attempt is for calibration data. + No attempt will be made to correlate the touch screen + and LCD co-ordinates. */ /**************************************************************************/ -tsTouchError_t tsRead(tsTouchData_t* data) +tsTouchError_t tsRead(tsTouchData_t* data, uint8_t calibrating) { uint32_t x1, x2, y1, y2, z1, z2; @@ -400,9 +414,20 @@ tsTouchError_t tsRead(tsTouchData_t* data) tsPoint_t location, touch; touch.x = x1; touch.y = y1; - getDisplayPoint( &location, &touch, &_tsMatrix) ; - data->xlcd = location.x; - data->ylcd = location.y; + // Only calculate the relative LCD value if this isn't for calibration + if (!calibrating) + { + getDisplayPoint( &location, &touch, &_tsMatrix) ; + data->xlcd = location.x; + data->ylcd = location.y; + } + else + { + // Assign some false values, but only xraw and yraw are + // used for calibration + data->xlcd = 0; + data->ylcd = 0; + } data->valid = true; return TS_ERROR_NONE; @@ -508,7 +533,7 @@ tsTouchError_t tsWaitForEvent(tsTouchData_t* data, uint32_t timeoutMS) { if (!_tsInitialised) tsInit(); - tsRead(data); + tsRead(data, false); // Return the results right away if reading is valid if (data->valid) @@ -530,7 +555,7 @@ tsTouchError_t tsWaitForEvent(tsTouchData_t* data, uint32_t timeoutMS) { return TS_ERROR_TIMEOUT; } - tsRead(data); + tsRead(data, false); } } // No systick rollover will occur ... calculate timeout the simple way @@ -544,7 +569,7 @@ tsTouchError_t tsWaitForEvent(tsTouchData_t* data, uint32_t timeoutMS) { return TS_ERROR_TIMEOUT; } - tsRead(data); + tsRead(data, false); } } } @@ -553,7 +578,7 @@ tsTouchError_t tsWaitForEvent(tsTouchData_t* data, uint32_t timeoutMS) { while (data->valid == false) { - tsRead(data); + tsRead(data, false); } } diff --git a/drivers/lcd/tft/touchscreen.h b/drivers/lcd/tft/touchscreen.h index ae49eb2..96f7626 100644 --- a/drivers/lcd/tft/touchscreen.h +++ b/drivers/lcd/tft/touchscreen.h @@ -93,14 +93,15 @@ typedef struct typedef enum { - TS_ERROR_NONE = 0, - TS_ERROR_TIMEOUT = -1, // Timeout occured before a valid reading - TS_ERROR_XYMISMATCH = -2 // Unable to get a stable X/Y value + TS_ERROR_NONE = 0, + TS_ERROR_TIMEOUT = -1, // Timeout occured before a valid reading + TS_ERROR_XYMISMATCH = -2, // Unable to get a stable X/Y value + TS_ERROR_NOTCALIBRATED = -3 // Can't calculate X/Y until tsCalibrate() is run! } tsTouchError_t; // Method Prototypes void tsInit ( void ); -tsTouchError_t tsRead(tsTouchData_t* data); +tsTouchError_t tsRead(tsTouchData_t* data, uint8_t calibrating); void tsCalibrate ( void ); tsTouchError_t tsWaitForEvent(tsTouchData_t* data, uint32_t timeoutMS); int tsSetThreshhold(uint8_t value); diff --git a/drivers/sensors/pn532/pn532.h b/drivers/sensors/pn532/pn532.h index d6fa5ac..9ec700b 100644 --- a/drivers/sensors/pn532/pn532.h +++ b/drivers/sensors/pn532/pn532.h @@ -32,7 +32,8 @@ typedef enum pn532_error_e PN532_ERROR_TIMEOUTWAITINGFORCARD = 0x0B, // No card detected in field with the specified timeout PN532_ERROR_BLOCKREADFAILED = 0x0C, // Unexpected response to block read request PN532_ERROR_WRONGCARDTYPE = 0x0D, // Card is not the expected format (based on SENS_RES/ATQA value) - PN532_ERROR_ADDRESSOUTOFRANGE = 0x0E // Specified block and page is out of range + PN532_ERROR_ADDRESSOUTOFRANGE = 0x0E, // Specified block and page is out of range + PN532_ERROR_I2C_NACK = 0x0F // I2C Bus - No ACK was received for master to slave data transfer } pn532_error_t; typedef enum pn532_modulation_e diff --git a/drivers/sensors/pn532/pn532_bus.h b/drivers/sensors/pn532/pn532_bus.h index a322933..1628bc5 100644 --- a/drivers/sensors/pn532/pn532_bus.h +++ b/drivers/sensors/pn532/pn532_bus.h @@ -10,8 +10,8 @@ #include "projectconfig.h" #include "pn532.h" -// #define PN532_BUS_UART -#define PN532_BUS_I2C +#define PN532_BUS_UART +// #define PN532_BUS_I2C #define PN532_RSTPD_PORT (2) #define PN532_RSTPD_PIN (2) @@ -25,6 +25,7 @@ #define PN532_BUFFER_LEN (PN532_EXTENDED_FRAME__DATA_MAX_LEN + PN532_EXTENDED_FRAME__OVERHEAD) #define PN532_UART_BAUDRATE (115200) + #define PN532_I2C_ADDRESS (0x48) #define PN532_I2C_READBIT (0x01) diff --git a/sysinit.c b/sysinit.c index a3834b6..aedf9b3 100644 --- a/sysinit.c +++ b/sysinit.c @@ -202,6 +202,19 @@ void systemInit() // Initialise TFT LCD Display #ifdef CFG_TFTLCD lcdInit(); + // You may need to call the tsCalibrate() function to calibrate + // the touch screen is this has never been done. This only needs + // to be done once and the values are saved to EEPROM. This + // function can also be called from tsInit if it's more + // convenient + /* + #ifdef CFG_I2CEEPROM + if (eepromReadU8(CFG_EEPROM_TOUCHSCREEN_CALIBRATED) != 1) + { + tsCalibrate(); + } + #endif + */ #endif // Initialise Chibi diff --git a/tools/examples/sensors/pn532/ISO14443A_ID/main.c b/tools/examples/sensors/pn532/ISO14443A_ID/main.c index fb6066e..22f4f0e 100644 --- a/tools/examples/sensors/pn532/ISO14443A_ID/main.c +++ b/tools/examples/sensors/pn532/ISO14443A_ID/main.c @@ -80,59 +80,79 @@ int main (void) while (1) { printf("%s", CFG_PRINTF_NEWLINE); - printf("Wait for an ISO14443A card (Mifare Classic, etc.)%s", CFG_PRINTF_NEWLINE); + printf("Waiting for an ISO14443A card (Mifare Classic, etc.)%s", CFG_PRINTF_NEWLINE); - // Send the command + // Send the command (and handle the most common errors) error = pn532Write(abtCommand, sizeof(abtCommand)); - - // Wait until we get a response or an unexpected error message - do - { - error = pn532Read(response, &responseLen); - systickDelay(25); - } - #ifdef PN532_UART - while (error == PN532_ERROR_RESPONSEBUFFEREMPTY); - #endif - #ifdef PN532_SPI - while ((error == PN532_ERROR_RESPONSEBUFFEREMPTY) || (error = PN532_ERROR_SPIREADYSTATUSTIMEOUT)); - #endif - - // Print the card details if possible - if (!error) + if (error) { - /* Response for ISO14443A 106KBPS (Mifare Classic, etc.) - See UM0701-02 section 7.3.5 for more information - - byte Description - ------------- ------------------------------------------ - b7 Tags Found - b8 Tag Number (only one used in this example) - b9..10 SENS_RES - b11 SEL_RES - b12 NFCID Length - b13..NFCIDLen NFCID - - SENS_RES SEL_RES Manufacturer/Card Type NFCID Len - -------- ------- ----------------------- --------- - 00 04 08 NXP Mifare Classic 1K 4 bytes */ - - printf("%s", CFG_PRINTF_NEWLINE); - printf("%-12s: %d %s", "Tags Found", response[7], CFG_PRINTF_NEWLINE); - printf("%-12s: %02X %02X %s", "SENS_RES", response[9], response[10], CFG_PRINTF_NEWLINE); - printf("%-12s: %02X %s", "SEL_RES", response[11], CFG_PRINTF_NEWLINE); - printf("%-12s: ", "NFCID"); - size_t pos; - for (pos=0; pos < response[12]; pos++) + // Something went wrong sending the command (probably the bus selection or wiring) + switch(error) { - printf("%02x ", response[13 + pos]); + case (PN532_ERROR_NOACK): + // No ACK frame received in UART mode (bus pins not set correctly?) + printf("Ooops ... No ACK frame was received! Are the bus pins sets to UART?%s", CFG_PRINTF_NEWLINE); + break; + case (PN532_ERROR_I2C_NACK): + // No ACK bit received to I2C start (bus pins not set correctly?) + printf("Ooops ... No ACK bit received for I2C start! Are the bus pins sets to I2C?%s", CFG_PRINTF_NEWLINE); + break; + default: + printf("Ooops ... something went wrong! [PN532 Error Code: 0x%02X]%s", error, CFG_PRINTF_NEWLINE); + break; } - printf(CFG_PRINTF_NEWLINE); } else { - // Oops .... something bad happened. Check 'error' - printf("Ooops! Error %02X %s", error, CFG_PRINTF_NEWLINE); + // Commmand seems to have gone through ... + do + { + // Keep reading until we get a response or an unexpected error condition + error = pn532Read(response, &responseLen); + systickDelay(25); + } + while (error == PN532_ERROR_RESPONSEBUFFEREMPTY); + + // Print the card details if possible + if (!error) + { + /* Response for ISO14443A 106KBPS (Mifare Classic, etc.) + See UM0701-02 section 7.3.5 for more information + + byte Description + ------------- ------------------------------------------ + b7 Tags Found + b8 Tag Number (only one used in this example) + b9..10 SENS_RES + b11 SEL_RES + b12 NFCID Length + b13..NFCIDLen NFCID + + SENS_RES SEL_RES Manufacturer/Card Type NFCID Len + -------- ------- ----------------------- --------- + 00 04 08 NXP Mifare Classic 1K 4 bytes */ + + printf("%s", CFG_PRINTF_NEWLINE); + printf("%-12s: %d %s", "Tags Found", response[7], CFG_PRINTF_NEWLINE); + printf("%-12s: %02X %02X %s", "SENS_RES", response[9], response[10], CFG_PRINTF_NEWLINE); + printf("%-12s: %02X %s", "SEL_RES", response[11], CFG_PRINTF_NEWLINE); + printf("%-12s: ", "NFCID"); + size_t pos; + for (pos=0; pos < response[12]; pos++) + { + printf("%02x ", response[13 + pos]); + } + printf(CFG_PRINTF_NEWLINE); + if ((response[9] == 0x00) && (response[10] == 0x04) && (response[11] == 0x08)) + { + printf("Seems to be a Mifare Classic 1K Card%s", CFG_PRINTF_NEWLINE); + } + } + else + { + // Oops .... something bad happened. Check 'error' + printf("Ooops! Error %02X %s", error, CFG_PRINTF_NEWLINE); + } } // Wait at least one second before trying again -- 2.20.1