HiPi
view release on metacpan or search on metacpan
lib/HiPi/Interface/MFRC522.pm view on Meta::CPAN
my @buffer = ();
while (!$uidComplete) {
#// Set the Cascade Level in the SEL byte, find out if we need to use the Cascade Tag in byte 2.
$selectDone = 0;
if( $cascadeLevel == 1 ) {
$buffer[0] = MIFARE_SELECT_CL1;
$uidIndex = 0,
$useCascadeTag = ( $validbits && $uid->{'size'} > 4 ) ? 1 : 0;
} elsif( $cascadeLevel == 2 ) {
$buffer[0] = MIFARE_SELECT_CL2;
$uidIndex = 3,
$useCascadeTag = ( $validbits && $uid->{'size'} > 7 ) ? 1 : 0;
} elsif( $cascadeLevel == 3 ) {
$buffer[0] = MIFARE_SELECT_CL3;
$uidIndex = 6,
$useCascadeTag = 0
} else {
# should not get here
# warn qq( cascade level $cascadeLevel);
return ( MFRC522_STATUS_INTERNAL_ERROR );
}
# // How many UID bits are known in this Cascade Level?
$currentLevelKnownBits = $validbits - (8 * $uidIndex);
if ($currentLevelKnownBits < 0) {
$currentLevelKnownBits = 0;
}
# // Copy the known bits from uid->uidByte[] to buffer[]
$index = 2; #// destination index in buffer[]
if ($useCascadeTag) {
$buffer[$index++] = MIFARE_CASCADE;
}
my $bytesToCopy = int($currentLevelKnownBits / 8) + ($currentLevelKnownBits % 8 ? 1 : 0); # // The number of bytes needed to represent the known bits for this level.
if ($bytesToCopy) {
my $maxBytes = $useCascadeTag ? 3 : 4; #// Max 4 bytes in each Cascade Level. Only 3 left if we use the Cascade Tag
if ($bytesToCopy > $maxBytes) {
$bytesToCopy = $maxBytes;
}
for (my $count = 0; $count < $bytesToCopy; $count++) {
$buffer[$index++] = $uid->{'data'}->[$uidIndex + $count] || 0;
}
}
# // Now that the data has been copied we need to include the 8 bits in CT in currentLevelKnownBits
if ($useCascadeTag) {
$currentLevelKnownBits += 8;
}
# // Repeat anti collision loop until we can transmit all UID bits + BCC and receive a SAK - max 32 iterations.
while (!$selectDone) {
# // Find out how many bits and bytes to send and receive.
if ($currentLevelKnownBits >= 32) { # // All UID bits in this Cascade Level are known. This is a SELECT.
$buffer[1] = 0x70; #// NVB - Number of Valid Bits: Seven whole bytes
#// Calculate BCC - Block Check Character
for( 2,3,4,5) {
$buffer[$_] //= 0;
}
$buffer[6] = $buffer[2] ^ $buffer[3] ^ $buffer[4] ^ $buffer[5];
# // Calculate CRC_A
my @crcdata = @buffer[0..6];
( $crcstatus, $cbuffer1, $cbuffer2 ) = $self->pcd_calculate_crc( \@crcdata );
if ($crcstatus != MFRC522_STATUS_OK) {
return ( $crcstatus, undef, undef );
}
# set the crc result
$buffer[7] = $cbuffer1;
$buffer[8] = $cbuffer2;
$txLastBits = 0; #// 0 => All 8 bits are valid.
$bufferUsed = 9;
$responseLength = 3;
$responseIndex = 6;
} else { #// This is an ANTICOLLISION.
$txLastBits = $currentLevelKnownBits % 8;
my $count = int($currentLevelKnownBits / 8); #// Number of whole bytes in the UID part.
$index = 2 + $count; #// Number of whole bytes: SEL + NVB + UIDs
$buffer[1] = ($index << 4) + $txLastBits; #// NVB - Number of Valid Bits
$bufferUsed = $index + ($txLastBits ? 1 : 0);
$responseLength = 9 - $index;
$responseIndex = $index;
}
#// Set bit adjustments
$rxAlign = $txLastBits || 0; #// Having a separate variable is overkill. But it makes the next line easier to read.
$self->write_register(MFRC522_REG_BitFramingReg, ($rxAlign << 4) + $txLastBits); #// RxAlign = BitFramingReg[6..4]. TxLastBits = BitFramingReg[2..0]
#// Transmit the buffer and receive the response.
my $getlen = $responseLength;
my $sendlen = $bufferUsed -1;
my @sendbuffer = @buffer[0..$sendlen];
($respstatus, $respdata, $respvalidbits) = $self->pcd_transceive_data(\@sendbuffer, $txLastBits, $getlen, $rxAlign );
$txLastBits = $respvalidbits;
if($respdata && ref($respdata)) {
( run in 1.006 second using v1.01-cache-2.11-cpan-71847e10f99 )