Пример #1
0
static int eraseBlock(int32_t dev, uint32_t blockAddress) {

	uint32_t status;

	waitUntilReady(dev, 0xFFFFFFFF);

	// Unlock Command
	bpi_flash_write(dev, blockAddress, P30_BLOCK_LOCK_SETUP);
	bpi_flash_write(dev, blockAddress, P30_BLOCK_UNLOCK);

	//Erase
	bpi_flash_write(dev, blockAddress, P30_BLOCK_ERASE_SETUP);
	bpi_flash_write(dev, blockAddress, P30_BLOCK_ERASE_CONFIRM);

	// Attesa ready della flash
	waitUntilReady(dev, 0xFFFFFFFF);

	status = readFlashStatus(dev);
	bpi_flash_write(dev, 0x0, P30_CLEAR_STATUS);

	// Imposto Read Array Mode
	bpi_flash_write(dev, 0x0, P30_READ_ARRAY);

	return status;
}
Пример #2
0
/****************************************************************************
 *
 * writeFlashPage
 *
 * Description:
 *
 * Funzioni per la scrittura/lettura di pagine della flash StrataFlash Numonix P30
 * montata sulla A3818.
 * Riferimento: Buffer Program Flowchart (fig. 36) da datasheet
 *    Numonyx Strataflash Embedded memory P30 (306666-12 - Agosto 2008).
 *
 * Parameters:
 *  
 *    IN      dev    - A3818 driver handle
 *
 *    IN      data   - the buffer containing data to be programmed.
 *
 *    IN      wordAddress  - the flash address to be programmed.
 *
 *    IN      numwords - the number of words (ie two bytes) of data contained in the buffer.
 *                                This is a X16 write buffer routine and the part expects a count in # of words
 *
 * Returns:
 *    
 *    int    TBD
 * 
 * Assumptions:
 *
 *    NONE
 *
 ***************************************************************************/
static int writeFlashPage(int32_t dev, uint32_t *data, int wordAddress,
		int numWords) {
	int i;

	// La modalit� di scrittura con buffer ha un massimo di 32 word a 16 bit
	// che possono essere scritte.
	if (numWords > 32)
		return -1;

	// Imposto Read Array Mode
	bpi_flash_write(dev, 0x0, P30_READ_ARRAY);

	// Status check
	waitUntilReady(dev, 0xFFFFFFFF);

	bpi_flash_write(dev, wordAddress, P30_BUFFERED_PROGRAM);
	bpi_flash_write(dev, wordAddress, numWords - 1); // N=16 words da scrivere (bisogna scrivere N-1)

	for (i = wordAddress; i < (wordAddress + numWords); ++i) {
		bpi_flash_write(dev, i, data[i - wordAddress]);
	}

	bpi_flash_write(dev, wordAddress, P30_BUFFERED_PROGRAM_CONFIRM);

	// Status check
	waitUntilReady(dev, 0xFFFFFFFF);

	// Imposto Read Array Mode
	bpi_flash_write(dev, 0x0, P30_READ_ARRAY);

	return 0;
}
Пример #3
0
void LR_IPC_IN::run()
{
	while (!threadShouldExit())
	{
		char line[256] = { '\0' };
		int sizeRead = 0;
		bool canReadLine = true;

		// parse input until we have a line, then process that line
		while (!String(line).endsWithChar('\n') && !threadShouldExit())
		{
			auto waitStatus = waitUntilReady(true, 0);
			if (waitStatus < 0)
			{
				canReadLine = false;
				break;
			}
			else if (waitStatus == 0)
			{
				wait(100);
				continue;
			}
			sizeRead += read(line + sizeRead, 1, false);
		}

		if (canReadLine)
		{
			String param(line);
			processLine(param);
		}
	}
}
Пример #4
0
error TCPListener::Accept(std::shared_ptr<TCPSocket>* clientSock) {
    if (clientSock == nullptr) {
        assert(0 && "clientSock must not be nullptr");
        return error::illegal_argument;
    }
    if (m_closed) {
        assert(0 && "Already closed");
        return error::illegal_state;
    }

    if (m_timeoutMilliseconds > 0) {
        fd_set readfds;
        error err = waitUntilReady(m_fd, &readfds, nullptr, nullptr, m_timeoutMilliseconds);
        if (err != error::nil) {
            return err;
        }
    }

    struct sockaddr_in clientAddr = {0};
    int addrlen = sizeof(clientAddr);
    SOCKET clientFD = accept(m_fd, (struct sockaddr*) &clientAddr, &addrlen);
    if (clientFD == INVALID_SOCKET) {
        return error::wrap(etype::os, WSAGetLastError());
    }

    std::string remoteAddr = inet_ntoa(clientAddr.sin_addr);
    uint16_t remotePort = ntohs(clientAddr.sin_port);
    *clientSock = std::make_shared<TCPSocket>(clientFD, std::move(remoteAddr), remotePort);
    return error::nil;
}
bool
xpcc::At45db0x1d<Spi, Cs>::initialize()
{
	Cs::set();
	Cs::setOutput();

	uint8_t status = readStatus();
	if (status == 0xff || status == 0) {
		// no device present
		return false;
	}

	if ((status & PAGE_SIZE) == 0)
	{
		// Page size is 264 (the default)
		// => set page size from 264 to 256 bytes
		Cs::reset();

		// send page size change sequence (fixed sequence)
		Spi::transferBlocking(0x3d);
		Spi::transferBlocking(0x2a);
		Spi::transferBlocking(0x80);
		Spi::transferBlocking(0xa6);

		Cs::set();
	}

	waitUntilReady();

	return true;
}
Пример #6
0
IdeError ideWriteSector( const void *buffer, IdeChannel channel, IdeDrive drive, u32 sector )
{
  ChannelCli( channel );

  if( !waitWhileBusy(channel) )  return IdeErrorTimeOut;

  WriteReg( channel, IdeRegNSec, 1 );
  WriteReg( channel, IdeReg0Sec, sector & 0x000000FF );
  WriteReg( channel, IdeReg1Sec, (sector & 0x0000FF00) >> 8 );
  WriteReg( channel, IdeReg2Sec, (sector & 0x00FF0000) >> 16 );
  WriteReg( channel, IdeReg3Sec, 0xE0 | ((sector & 0x0F000000)>>24) | ((drive & 0x1)<<4) );

  if( !waitWhileBusy(channel) )  return IdeErrorTimeOut;
  if( !waitUntilReady(channel) )  return IdeErrorTimeOut;

  WriteReg( channel, IdeRegCommand, IdeCmdWrite );

  if( !waitWhileBusy(channel) )  return IdeErrorTimeOut;
  if( !waitUntilDrq(channel) )  return IdeErrorTimeOut;
  if( (ReadReg(channel,IdeRegStatus) & IdeStatusError) )
  {
    u8 error = ReadReg( channel, IdeRegError );
    ResetController( channel );
    return error;
  };

  ASM("cld ; rep ; outsw" :: "d" (channel + IdeRegData), "c" (0x100), "S" (buffer) );

  ChannelSti( channel );
  return 0;
};
Пример #7
0
extern "C" void* NdbThreadFuncUpdate(void* pArg)
{
    myRandom48Init((long int)NdbTick_CurrentMillisecond());
    unsigned nSucc = 0;
    unsigned nFail = 0;
    Ndb* pNdb = NULL ;
    pNdb = new Ndb("TEST_DB");
    VerifyMethodInt(pNdb, init());
    VerifyMethodInt(pNdb, waitUntilReady());

    while(NdbMutex_Trylock(g_pNdbMutex)) {
        Uint32 nWarehouse = myRandom48(g_nWarehouseCount);
        NdbConnection* pNdbConnection = NULL ;
        VerifyMethodPtr(pNdbConnection, pNdb, startTransaction());
        CHK_TR(pNdbConnection) ; // epaulsa
        NdbOperation* pNdbOperationW = NULL ;
        VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse));
        VerifyMethodInt(pNdbOperationW, interpretedUpdateTuple());
        VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse));
        VerifyMethodInt(pNdbOperationW, incValue(c_szWarehouseCount, Uint32(1)));
        Uint32 nWarehouseSum = 0;
        for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) {
            NdbOperation* pNdbOperationD = NULL ;
            VerifyMethodPtr(pNdbOperationD, pNdbConnection, getNdbOperation(c_szDistrict));
            VerifyMethodInt(pNdbOperationD, interpretedUpdateTuple());
            VerifyMethodInt(pNdbOperationD, equal(c_szDistrictWarehouseNumber, nWarehouse));
            VerifyMethodInt(pNdbOperationD, equal(c_szDistrictNumber, nDistrict));
            VerifyMethodInt(pNdbOperationD, incValue(c_szDistrictCount, Uint32(1)));
            Uint32 nDistrictSum = myRandom48(100);
            nWarehouseSum += nDistrictSum;
            VerifyMethodInt(pNdbOperationD, setValue(c_szDistrictSum, nDistrictSum));
        }
        VerifyMethodInt(pNdbOperationW, setValue(c_szWarehouseSum, nWarehouseSum));
        int iExec = pNdbConnection->execute(Commit);
        int iError = pNdbConnection->getNdbError().code;

        if(iExec<0 && iError!=0 && iError!=266 && iError!=626) {
            ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__);
        }
        if(iExec==0) {
            ++nSucc;
        } else {
            ++nFail;
        }
        VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection));
    }
    ndbout << "update: " << nSucc << " succeeded, " << nFail << " failed " << endl;
    NdbMutex_Unlock(g_pNdbMutex);
    delete pNdb;
    pNdb = NULL ;
    return NULL;
}
Пример #8
0
error ConnectTCP(const std::string& host, uint16_t port, int64_t timeoutMilliseconds,
        std::shared_ptr<TCPSocket>* clientSock) {
    if (clientSock == nullptr) {
        assert(0 && "clientSock must not be nullptr");
        return error::illegal_argument;
    }

    internal::init();

    std::string remoteAddr;
    error addrErr = LookupAddress(host, &remoteAddr);
    if (addrErr != error::nil) {
        return addrErr;
    }

    SOCKET fd = socket(AF_INET, SOCK_STREAM, 0);
    if (fd == INVALID_SOCKET) {
        return error::wrap(etype::os, WSAGetLastError());
    }

    struct sockaddr_in serverAddr = {0};
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(port);
    serverAddr.sin_addr.S_un.S_addr = inet_addr(remoteAddr.c_str());

    if (timeoutMilliseconds <= 0) { // connect in blocking mode
        if (connect(fd, (struct sockaddr*) &serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
            int connErr = WSAGetLastError();
            closesocket(fd);
            return error::wrap(etype::os, connErr);
        }
    } else { // connect in non blocking mode
        ioctlsocket(fd, FIONBIO, &kNonBlockingMode);
        if (connect(fd, (struct sockaddr*) &serverAddr, sizeof(serverAddr)) == SOCKET_ERROR) {
            int connErr = WSAGetLastError();
            if (connErr != WSAEWOULDBLOCK) {
                closesocket(fd);
                return error::wrap(etype::os, connErr);
            }
        }
        fd_set writefds, exceptfds;
        error err = waitUntilReady(fd, nullptr, &writefds, &exceptfds, timeoutMilliseconds);
        if (err != error::nil) {
            closesocket(fd);
            return err;
        }
        ioctlsocket(fd, FIONBIO, &kBlockingMode);
    }

    *clientSock = std::make_shared<TCPSocket>(fd, std::move(remoteAddr), port);
    return error::nil;
}
void
xpcc::At45db0x1d<Spi, Cs>::blockErase(uint16_t blockAddress)
{
	waitUntilReady();

	Cs::reset();

	// set address
	Spi::transferBlocking(blockAddress >> 8);
	Spi::transferBlocking(blockAddress & 0xf8);
	Spi::transferBlocking(0);

	Cs::set();
}
Пример #10
0
error TCPSocket::Write(const char* buf, size_t len, int* nbytes) {
    if (m_closed) {
        assert(0 && "Already closed");
        return error::illegal_state;
    }

    if (m_timeoutMilliseconds > 0) {
        fd_set writefds;
        error err = waitUntilReady(m_fd, nullptr, &writefds, nullptr, m_timeoutMilliseconds);
        if (err != error::nil) {
            return err;
        }
    }
    return write(m_fd, buf, len, nbytes);
}
void
xpcc::At45db0x1d<Spi, Cs>::chipErase()
{
	waitUntilReady();

	Cs::reset();

	// send chip erase sequence (fixed sequence)
	Spi::transferBlocking(0xc7);
	Spi::transferBlocking(0x94);
	Spi::transferBlocking(0x80);
	Spi::transferBlocking(0x9a);

	Cs::set();
}
uchar   ispChipErase(stkChipEraseIsp_t *param)
{
uchar   maxDelay = param->eraseDelay;
uchar   rval = STK_STATUS_CMD_OK;

    ispBlockTransfer(param->cmd, 4);
    if(param->pollMethod != 0){
        if(maxDelay < 10)   /* allow at least 10 ms */
            maxDelay = 10;
        rval = waitUntilReady(maxDelay);
    }else{
        timerMsDelay(maxDelay);
    }
    return rval;
}
Пример #13
0
DatagramSocket* DatagramSocket::waitForNextConnection() const
{
    while (waitUntilReady (true, -1) == 1)
    {
        struct sockaddr_storage address;
        juce_socklen_t len = sizeof (address);
        char buf[1];

        if (recvfrom (handle, buf, 0, 0, (struct sockaddr*) &address, &len) > 0)
            return new DatagramSocket (inet_ntoa (((struct sockaddr_in*) &address)->sin_addr),
                                       ntohs (((struct sockaddr_in*) &address)->sin_port),
                                       -1, -1);
    }

    return nullptr;
}
Пример #14
0
DatagramSocket* DatagramSocket::waitForNextConnection() const
{
    while (waitUntilReady (true, -1) == 1)
    {
        struct sockaddr_storage address;
        juce_socklen_t len = sizeof (address);
        char buf[1];

		if (recvfrom(handle, buf, 0, 0, (struct sockaddr*) &address, &len) > 0)
		{
			char str[INET_ADDRSTRLEN];			
			inet_ntop(AF_INET, &((struct sockaddr_in*) &address)->sin_addr, str, INET_ADDRSTRLEN);
			return new DatagramSocket(str, ntohs(((struct sockaddr_in*) &address)->sin_port), -1, -1);
		}
    }

    return nullptr;
}
Пример #15
0
void X86AtaDevice::identify() const
{
    // Set features register. 0 = PIO, 1 = DMA.
    outb(_ioPort + 1, 0);
    outb(_controlPort, 0);

    // select device
    outb(_ioPort + kAtaRegisterDriveSelect, 0xA0 | _slaveBit << 4);
    ioWait();

    switch (type()) {
        case Type::PATAPI:
        case Type::SATAPI:
            // send IDENTIFY PACKET DEVICE
            outb(_ioPort + 0x07, 0xA1); break;
        case Type::PATA:
        case Type::SATA:
            // send IDENTIFY DEVICE
            outb(_ioPort + 0x07, 0xEC); break;
        case Type::Unknown:
            return;
    }
    ioWait();

    // read in status
    waitUntilReady(false);

    // read in device information
    uint16_t identity[256];
    pioRead(identity, 256);

    _descriptor.readIdentity(identity);
    _identified = true;

    if (type() == Type::PATAPI) {
        uint16_t data[4];
        performPioAtapiOperation(AtapiCommand::readCapacityCommand(), data, sizeof(data));
        _descriptor.readAtapiCapacity(data);
    }
}
Пример #16
0
 DeviceStatus sendLowLevelCommand(const char* cmd, int timeOut) {
         waitUntilReady();
         setTimeOut(timeOut);
         formatLowLevelCommandString(cmd);
         return transmitToInstrument();
 }
Пример #17
0
extern "C" void* NdbThreadFuncRead(void* pArg)
{
    myRandom48Init((long int)NdbTick_CurrentMillisecond());
    unsigned nSucc = 0;
    unsigned nFail = 0;
    NdbRecAttr** ppNdbRecAttrDSum = new NdbRecAttr*[g_nDistrictPerWarehouse];
    NdbRecAttr** ppNdbRecAttrDCnt = new NdbRecAttr*[g_nDistrictPerWarehouse];
    Ndb* pNdb = NULL ;
    pNdb = new Ndb("TEST_DB");
    VerifyMethodInt(pNdb, init());
    VerifyMethodInt(pNdb, waitUntilReady());

    while(NdbMutex_Trylock(g_pNdbMutex)) {
        Uint32 nWarehouse = myRandom48(g_nWarehouseCount);
        NdbConnection* pNdbConnection = NULL ;
        VerifyMethodPtr(pNdbConnection, pNdb, startTransaction());
        CHK_TR(pNdbConnection) ; // epaulsa
        NdbOperation* pNdbOperationW = NULL ;
        VerifyMethodPtr(pNdbOperationW, pNdbConnection, getNdbOperation(c_szWarehouse));
        VerifyMethodInt(pNdbOperationW, readTuple());
        VerifyMethodInt(pNdbOperationW, equal(c_szWarehouseNumber, nWarehouse));
        NdbRecAttr* pNdbRecAttrWSum;
        VerifyMethodPtr(pNdbRecAttrWSum, pNdbOperationW, getValue(c_szWarehouseSum, 0));
        NdbRecAttr* pNdbRecAttrWCnt;
        VerifyMethodPtr(pNdbRecAttrWCnt, pNdbOperationW, getValue(c_szWarehouseCount, 0));
        for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) {
            NdbOperation* pNdbOperationD = NULL ;
            VerifyMethodPtr(pNdbOperationD, pNdbConnection, getNdbOperation(c_szDistrict));
            VerifyMethodInt(pNdbOperationD, readTuple());
            VerifyMethodInt(pNdbOperationD, equal(c_szDistrictWarehouseNumber, nWarehouse));
            VerifyMethodInt(pNdbOperationD, equal(c_szDistrictNumber, nDistrict));
            VerifyMethodPtr(ppNdbRecAttrDSum[nDistrict], pNdbOperationD, getValue(c_szDistrictSum, 0));
            VerifyMethodPtr(ppNdbRecAttrDCnt[nDistrict], pNdbOperationD, getValue(c_szDistrictCount, 0));
        }
        int iExec = pNdbConnection->execute(Commit);
        int iError = pNdbConnection->getNdbError().code;

        if(iExec<0 && iError!=0 && iError!=266 && iError!=626) {
            ReportMethodInt(iExec, pNdbConnection, "pNdbConnection", "execute(Commit)", __FILE__, __LINE__);
        }
        if(iExec==0) {
            Uint32 nSum = 0;
            Uint32 nCnt = 0;
            for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) {
                nSum += ppNdbRecAttrDSum[nDistrict]->u_32_value();
                nCnt += ppNdbRecAttrDCnt[nDistrict]->u_32_value();
            }
            if(nSum!=pNdbRecAttrWSum->u_32_value()
                    || nCnt!=g_nDistrictPerWarehouse*pNdbRecAttrWCnt->u_32_value()) {
                ndbout << "INCONSISTENT!" << endl;
                ndbout << "iExec==" << iExec << endl;
                ndbout << "iError==" << iError << endl;
                ndbout << endl;
                ndbout << c_szWarehouseSum << "==" << pNdbRecAttrWSum->u_32_value() << ", ";
                ndbout << c_szWarehouseCount << "==" << pNdbRecAttrWCnt->u_32_value() << endl;
                ndbout << "nSum==" << nSum << ", nCnt=" << nCnt << endl;
                for(Uint32 nDistrict=0; nDistrict<g_nDistrictPerWarehouse; ++nDistrict) {
                    ndbout << c_szDistrictSum << "[" << nDistrict << "]==" << ppNdbRecAttrDSum[nDistrict]->u_32_value() << ", ";
                    ndbout << c_szDistrictCount << "[" << nDistrict << "]==" << ppNdbRecAttrDCnt[nDistrict]->u_32_value() << endl;
                }
                VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection));
                delete pNdb;
                pNdb = NULL ;
                delete[] ppNdbRecAttrDSum;
                ppNdbRecAttrDSum = NULL ;
                delete[] ppNdbRecAttrDCnt;
                ppNdbRecAttrDCnt = NULL ;
                NDBT_ProgramExit(NDBT_FAILED);
            }
            ++nSucc;
        } else {
            ++nFail;
        }
        VerifyMethodVoid(pNdb, closeTransaction(pNdbConnection));
    }
    ndbout << "read: " << nSucc << " succeeded, " << nFail << " failed " << endl;
    NdbMutex_Unlock(g_pNdbMutex);
    delete pNdb;
    pNdb = NULL ;
    delete[] ppNdbRecAttrDSum;
    ppNdbRecAttrDSum = NULL ;
    delete[] ppNdbRecAttrDCnt;
    ppNdbRecAttrDCnt = NULL ;
    return NULL;
}
boolean Adafruit_NFCShield_I2C::inDataExchange(uint8_t * send, uint8_t sendLength, uint8_t * response, uint8_t * responseLength) {
  if (sendLength > PN532_PACKBUFFSIZ -2) {
    #ifdef PN532DEBUG
      Serial.println("APDU length too long for packet buffer");
    #endif
    return false;
  }
  uint8_t i;
  
  pn532_packetbuffer[0] = 0x40; // PN532_COMMAND_INDATAEXCHANGE;
  pn532_packetbuffer[1] = inListedTag;
  for (i=0; i<sendLength; ++i) {
    pn532_packetbuffer[i+2] = send[i];
  }
  
  if (!sendCommandCheckAck(pn532_packetbuffer,sendLength+2,1000)) {
    #ifdef PN532DEBUG
      Serial.println("Could not send ADPU");
    #endif
    return false;
  }

  if (!waitUntilReady(1000)) {
    #ifdef PN532DEBUG
      Serial.println("Response never received for ADPU...");
    #endif
    return false;
  }

  wirereaddata(pn532_packetbuffer,sizeof(pn532_packetbuffer));
  
  if (pn532_packetbuffer[0] == 0 && pn532_packetbuffer[1] == 0 && pn532_packetbuffer[2] == 0xff) {
    uint8_t length = pn532_packetbuffer[3];
    if (pn532_packetbuffer[4]!=(uint8_t)(~length+1)) {
      #ifdef PN532DEBUG
        Serial.println("Length check invalid");
        Serial.println(length,HEX);
        Serial.println((~length)+1,HEX);
      #endif
      return false;
    }
    if (pn532_packetbuffer[5]==PN532_PN532TOHOST && pn532_packetbuffer[6]==PN532_RESPONSE_INDATAEXCHANGE) {
      if ((pn532_packetbuffer[7] & 0x3f)!=0) {
        #ifdef PN532DEBUG
          Serial.println("Status code indicates an error");
        #endif
        return false;
      }
      
      length -= 3;
      
      if (length > *responseLength) {
        length = *responseLength; // silent truncation...
      }
      
      for (i=0; i<length; ++i) {
        response[i] = pn532_packetbuffer[8+i];
      }
      *responseLength = length;
      
      return true;
    } 
    else {
      Serial.print("Don't know how to handle this command: ");
      Serial.println(pn532_packetbuffer[6],HEX);
      return false;
    } 
  } 
  else {
    Serial.println("Preamble missing");
    return false;
  }
}
Пример #19
0
         // Change the device address (unless it's not addressable)
 DeviceStatus sendCommand(const char* cmd) {
         waitUntilReady();
         setTimeOut();
         formatCommandString(cmd);
         return transmitToInstrument();
 }
boolean Adafruit_NFCShield_I2C::inListPassiveTarget() {
  pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
  pn532_packetbuffer[1] = 1;
  pn532_packetbuffer[2] = 0;
  
  #ifdef PN532DEBUG 
    Serial.print("About to inList passive target");
  #endif

  if (!sendCommandCheckAck(pn532_packetbuffer,3,1000)) {
    #ifdef PN532DEBUG
      Serial.println("Could not send inlist message");
    #endif
    return false;
  }

  if (!waitUntilReady(30000)) {
    return false;
  }

  wirereaddata(pn532_packetbuffer,sizeof(pn532_packetbuffer));
  
  if (pn532_packetbuffer[0] == 0 && pn532_packetbuffer[1] == 0 && pn532_packetbuffer[2] == 0xff) {
    uint8_t length = pn532_packetbuffer[3];
    if (pn532_packetbuffer[4]!=(uint8_t)(~length+1)) {
      #ifdef PN532DEBUG
        Serial.println("Length check invalid");
        Serial.println(length,HEX);
        Serial.println((~length)+1,HEX);
      #endif
      return false;
    }
    if (pn532_packetbuffer[5]==PN532_PN532TOHOST && pn532_packetbuffer[6]==PN532_RESPONSE_INLISTPASSIVETARGET) {
      if (pn532_packetbuffer[7] != 1) {
        #ifdef PN532DEBUG
        Serial.println("Unhandled number of targets inlisted");
        #endif
        Serial.println("Number of tags inlisted:");
        Serial.println(pn532_packetbuffer[7]);
        return false;
      }
      
      inListedTag = pn532_packetbuffer[8];
      Serial.print("Tag number: ");
      Serial.println(inListedTag);
      
      return true;
    } else {
      #ifdef PN532DEBUG
        Serial.print("Unexpected response to inlist passive host");
      #endif
      return false;
    } 
  } 
  else {
    #ifdef PN532DEBUG
      Serial.println("Preamble missing");
    #endif
    return false;
  }

  return true;
}
uchar   ispProgramMemory(stkProgramFlashIsp_t *param, uchar isEeprom)
{
utilWord_t  numBytes;
uchar       rval = STK_STATUS_CMD_OK;
uchar       valuePollingMask, rdyPollingMask;
uint        i;

    numBytes.bytes[1] = param->numBytes[0];
    numBytes.bytes[0] = param->numBytes[1];
    if(param->mode & 1){    /* page mode */
        valuePollingMask = 0x20;
        rdyPollingMask = 0x40;
    }else{                  /* word mode */
        valuePollingMask = 4;
        rdyPollingMask = 8;
    }
    if(!isEeprom && stkAddress.bytes[3] & 0x80){
        cmdBuffer[0] = 0x4d;    /* load extended address */
        cmdBuffer[1] = 0x00;
        cmdBuffer[2] = stkAddress.bytes[2];
        cmdBuffer[3] = 0x00;
        ispBlockTransfer(cmdBuffer, 4);
    }
    for(i = 0; rval == STK_STATUS_CMD_OK && i < numBytes.word; i++){
        uchar x;
        wdt_reset();
        cmdBuffer[1] = stkAddress.bytes[1];
        cmdBuffer[2] = stkAddress.bytes[0];
        cmdBuffer[3] = param->data[i];
        x = param->cmd[0];
        if(!isEeprom){
            x &= ~0x08;
            if((uchar)i & 1){
                x |= 0x08;
                stkIncrementAddress();
            }
        }else{
            stkIncrementAddress();
        }
        cmdBuffer[0] = x;
#if 0   /* does not work this way... */
        if(cmdBuffer[3] == 0xff && !(param->mode & 1) && !isEeprom)   /* skip 0xff in word mode */
            continue;
#endif
        ispBlockTransfer(cmdBuffer, 4);
        if(param->mode & 1){            /* is page mode */
            if(i < numBytes.word - 1 || !(param->mode & 0x80))
                continue;               /* not last byte written */
            cmdBuffer[0] = param->cmd[1];     /* write program memory page */
            ispBlockTransfer(cmdBuffer, 4);
        }
        /* poll for ready after each byte (word mode) or page (page mode) */
        if(param->mode & valuePollingMask){ /* value polling */
            uchar d = param->data[i];
            if(d == param->poll[0] || d == param->poll[1]){ /* must use timed polling */
                timerMsDelay(param->delay);
            }else{
                uchar x = param->cmd[2];     /* read flash */
                x &= ~0x08;
                if((uchar)i & 1){
                    x |= 0x08;
                }
                cmdBuffer[0] = x;
                timerSetupTimeout(param->delay);
                while(ispBlockTransfer(cmdBuffer, 4) != d){
                    if(timerTimeoutOccurred()){
                        rval = STK_STATUS_CMD_TOUT;
                        break;
                    }
                }
            }
        }else if(param->mode & rdyPollingMask){ /* rdy/bsy polling */
            rval = waitUntilReady(param->delay);
        }else{                          /* must be timed delay */
            timerMsDelay(param->delay);
        }
    }
    return rval;
}