I have PN532 chip for NFC and my board is connected to it by SPI. I am shure, that connection is good (Mifare UL totally works). I have some blank 1K classic cards, and there is some troubles.
My moves:
1) Setup PN532 (retries, SAM)
2) search for card by ListPassiveTarget command for ISO14443A cards
3) when card is found, authenticate to some sector (required block_number = sector_number * 4)
4) read data by 4 InDataExchange commands. Required block_number = sector_number * 4 + 0, 1, 2, 3.
5) go to step 3
First sector read is ok, I have some good data. But when I try to read other sector after succesfull authorisation to it, I have an error like I failed authentication.
I tried to read sector 0 (OK), then sector 1..15 read is failed.
I tried to read sector 5 (OK) with all block_num calculations (20,21,22,23 block), then sector 6..15 read is failed.
I tried to remove card from field for a minute, return card to field and repeat reading - and I cant read any sector. Only rebooting helps.
I suppose, that there can be some move between authentications. Typical HALT command is not helping.
Authentication function is tested - wrong keys dont work, wright keys are working.
My code, that dealing with reading:
// here we know card type
// ISO 14443 A MIFARE CLASSIC 1K
// repeat polling
if( !ListPassiveTarget_14443A_106() )
{
// no card!
NFC_download = false;
break;
}
else
{
if( !GetGeneralStatus() )
{
// no card!
NFC_download = false;
break;
}
else
{
if( NFC::Num_Of_Tg != 0 )
{
// 14443 A Mifare Classic
// 16 sectors, 4 blocks in each
for(u8 sector = 0; sector < 16; sector++) // for all 16 sectors
{
// autentificate sector with A key
u8 x = 0;
for(x = 0; (x < 3) && (Autenticated == 0); x++) // loop for keys
{
Autenticated = Try_Mifare_Classic_Key( x, 0, sector ); // try A key
// block = sector*4
}
if( Autenticated != 0 )
{
// send up success and key num
// uart send
if( ((Uart::CommandTX_WPos + 1) & 0x0F) != Uart::CommandTX_RPos )
{
// ok
Uart::CommandTXBuf[Uart::CommandTX_WPos].Size = 4;
Uart::CommandTXBuf[Uart::CommandTX_WPos].Buf[0] = AUTH_CLASSIC;
Uart::CommandTXBuf[Uart::CommandTX_WPos].Buf[1] = Autenticated; // key type
Uart::CommandTXBuf[Uart::CommandTX_WPos].Buf[2] = x; // key number
Uart::CommandTXBuf[Uart::CommandTX_WPos].Buf[3] = sector; // sector
Uart::CommandTX_WPos = (Uart::CommandTX_WPos + 1) & 0x0F;
Uart::commandSend();
}
// read all the sector
Read_Mifare( sector*4 );
Read_Mifare( sector*4 + 1);
Read_Mifare( sector*4 + 2);
Read_Mifare( sector*4 + 3);
// reboot card?
//SPI::Wait(5500000); // 1000 ms delay
//Halt_Mifare(); // halt wont help
//SPI::Wait(550000); // 100 ms delay
}
}// for sectors
}
else
{
// no target
NFC_download = false;
break;
}
}
}
What can be wrong? I have missed some moves between sector authentications and readings?
Fail in logic. Forgot to clear authentication flag. Now it's working.
Related
I am making a USB Bootloader for PIC24FJ. I am now in the process of writing to flash memory the application code hex file through a software and without using ICD3. After downloading the application code hex file, I checked the program memory of the PIC using the PIC Memory Views of MPLAB Window Toolbar, and this is what it looks like. PIC24_BOOT_APP_VECTOR_AREA As you can see in the picture, the opcode is not continuously written in every address. It alternates with 000000.
Also I compared the opcodes of the downloaded app code using the bootloader, to the application code without using the bootloader. I have found out that there are data in the opcodes that are not present in the application alone. Attached are the photos. Application_Code_Alone_User_Area, PIC24_Boot_App_User_Area This may create a problem in jumping to the application.
Below is my code for storing data in the buffer and writing to flash memory. (I use single word programming for flash)
#define WRITE_FLASH_BLOCK_SIZE 0x04
#define USER_MEM_START_ADDRESS 0x004002
unsigned long rxBuff[60];
int rxIndexer;
int xfer;
lineStart = rxBuff[ 0 ];
positionAddress = (rxBuff[ 2 ] << 8) + (rxBuff[ 3 ]); // THIS IS THE ADDRESS WHERE THE DATA SHOULD BE ADDRESSED
numberOfData = rxBuff[ 1 ]; // THIS IS THE TOTAL NUMBER OF DATA RECEIVED IN THE STREAM
recordType = rxBuff[ 4 ];
rxIndexer = 5; //Start of data index in a INTEL Hex file format
for(xfer = 0; xfer < numberOfData; xfer += WRITE_FLASH_BLOCK_SIZE) // THIS SECTION CONTAINS THE PROCESS OF COMBINING THE INFORMATION
{ // FROM THE DATA STREAM TO THIS FORMAT - 0x00AA, 0xBBCC
rxBuff[rxIndexer] = ((rxBuff[START_OF_DATA_INDEX + xfer]) &0x00FF);
rxBuff[rxIndexer] |= ((rxBuff[START_OF_DATA_INDEX + xfer + 1] << 8) &0xFF00); //end of lower word
rxIndexer++;
rxBuff[rxIndexer] = ((rxBuff[START_OF_DATA_INDEX + xfer + 2]) &0x00FF); //start of upper byte
rxBuff[rxIndexer] |= ((0x00 << 8) & 0xFF00); // phantom byte (0x00)
rxIndexer++;
}
if(lineStart == ':')
{
if(recordType == 0x00 && data_checksum == 0)
{
for(xfer = 0; xfer < numberOfData; xfer += 2)
{
FlashWrite_Word(programAddress + positionAddress, rxBuff[5 + xfer], rxBuff[5 + xfer + 1]);
positionAddress += 2;
}
}
else if(recordType == 0x04 && data_checksum == 0)
{
programAddress = USER_MEM_START_ADDRESS;
}
else if( recordType == END_OF_FILE_RECORD)
{
jumpTo_App();
}
Having IPv4 address ranges for a given country, how would one generate random address? For example, a single current set of ranges (one of many) for Singapore is:
+----------+----------+--------------+
| ip_from | ip_to | country_code |
+----------+----------+--------------+
| 18925568 | 18926079 | SG |
+----------+----------+--------------+
source: lite.ip2location.com
FAQ(3) explains that
IP_Number = 16777216*w + 65536*x + 256*y + z
where
IP_Address = w.x.y.z
IP_Number standing either for ip_from or ip_to. For the Singapore range presented above, it gives me:
16777216*w + 65536*x + 256*y + z >= 18925568; // from
16777216*w + 65536*x + 256*y + z <= 18926079; // to
How can I generate random w, x, y and z?
Here is a testable implementation (in JavaScript since that can be run directly here) and a little bit of a description.
First you need to generate random number from the specified range. If you have a function (let's call it random) that generates random real numbers between 0 and 0.999... [0,1) then you can do this.
num = (random() * (end - start + 1)) + start
Then you need to use mod 256 4 times to split the number into 4 parts and also use div 256 3 times on the given number (the fourth div operation would be unnecessary but if we are doing it in loop then we can just keep it there for the sake of simplicity as it doesn't change a thing).
(% - modulo, // - div)
first = num % 256
num = num // 256
second = num % 256
num = num // 256
third = num % 256
num = num // 256
fourth = num % 256
You can then push them into an array [fourth, third, second, first] (note the order here) and do some validation - some addresses are reserved for private internets so if you happen to generate one of them, just throw it away and generate a new one (you can either loop or recurse here till you generate a valid one).
Ip addresses in these ranges are reserved according to RFC 1918:
10.0.0.0 - 10.255.255.255 (10/8 prefix)
172.16.0.0 - 172.31.255.255 (172.16/12 prefix)
192.168.0.0 - 192.168.255.255 (192.168/16 prefix)
And here is the implementation.
const start = 18925568;
const end = 18926079;
function _generateRandomIp(start, end) {
let r = Math.floor(Math.random() * (end - start + 1)) + start;
const ip = [];
for (let i = 0; i < 4; i++) {
ip.push(r % 256);
r = Math.floor(r / 256);
}
return ip.reverse(); // put the results mod/div into correct order
}
function generateRandomIp(start, end) {
let ip = _generateRandomIp(start, end);
let valid = true;
// ip can't be of format 10.xxx.xxx.xxx
if (ip[0] === 10) { valid = false; }
// ip can't be of format 172.16.xxx.xxx
if (ip[0] === 172 && ip[1] === 16) { valid = false; }
// ip can't be of format 192.168.xxx.xxx
if (ip[0] === 192 && ip[1] === 168) { valid = false; }
if (valid === true) {
return ip.join('.'); // convert ip to string format
} else {
return generateRandomIp(start, end); // try again
}
}
const ip = generateRandomIp(start, end);
console.log(ip);
The above snippet will generate a random ip address in that range each time you run it.
And here is the test case from the page that you have mentioned which says that number 3401190660 should be converted into 202.186.13.4, so let's just switch that randomly generated number for this one and try it.
const start = 18925568;
const end = 18926079;
function _generateRandomIp(start, end) {
let r = 3401190660; // here is that specific number
const ip = [];
for (let i = 0; i < 4; i++) {
ip.push(r % 256);
r = Math.floor(r / 256);
}
return ip.reverse(); // put the results mod/div into correct order
}
function generateRandomIp(start, end) {
let ip = _generateRandomIp(start, end);
let valid = true;
// ip can't be of format 10.xxx.xxx.xxx
if (ip[0] === 10) { valid = false; }
// ip can't be of format 172.16.xxx.xxx
if (ip[0] === 172 && ip[1] === 16) { valid = false; }
// ip can't be of format 192.168.xxx.xxx
if (ip[0] === 192 && ip[1] === 168) { valid = false; }
if (valid === true) {
return ip.join('.'); // convert ip to string format
} else {
return generateRandomIp(start, end); // try again
}
}
const ip = generateRandomIp(start, end);
console.log(ip);
And as we can see, this algorithm produced the correct result.
I'm trying to read byte per byte from the RX FIFO, that's 8 bytes deep.
The problem is that when the first byte is received, I have to wait for 8 other bytes to finally get the first byte on U1RXREG.
I'd like to know how to perform some dummy reads on the FIFO to access a particuar byte and "flush" it. Simply putting U1RXREG in an array doesn't do the trick.
Here's my initialization :
void UART_Initialize(void)
{
// SIDL: Stop in Idle Mode bit : 1 = Discontinue module operation when the device enters Idle mode
U1MODEbits.SIDL = 0;
// IREN: IrDA Encoder and Decoder Enable bit : 0 = IrDA is disabled
U1MODEbits.IREN = 0;
// RTSMD: Mode Selection for UxRTS Pin bit : 0 = UxRTS pin is in Flow Control mode
U1MODEbits.RTSMD = 0;
// UEN<1:0>: UARTx Enable bits : 10 = UxTX, UxRX, UxCTS and UxRTS pins are enabled and used
U1MODEbits.UEN1 = 1;
U1MODEbits.UEN0 = 0;
// WAKE: Enable Wake-up on Start bit Detect During Sleep Mode bit : 0 = Wake-up disabled
U1MODEbits.WAKE = 0;
// LPBACK: UARTx Loopback Mode Select bit : 0 = Loopback mode is disabled
U1MODEbits.LPBACK = 0;
// ABAUD: Auto-Baud Enable bit : 0 = Baud rate measurement disabled or completed
U1MODEbits.ABAUD = 0;
// RXINV: Receive Polarity Inversion bit : 0 = UxRX Idle state is ‘1’
U1MODEbits.RXINV = 0;
// BRGH: High Baud Rate Enable bit : 0 = Standard Speed mode – 16x baud clock enabled
U1MODEbits.BRGH = 0;
// PDSEL<1:0>: Parity and Data Selection bits : 01 = 8-bit data, even parity
U1MODEbits.PDSEL1 = 0;
U1MODEbits.PDSEL0 = 1;
// STSEL: Stop Selection bit : 0 = 1 Stop bit
U1MODEbits.STSEL = 0;
// ADM_EN: Automatic Address Detect Mode Enable bit : 0 = Automatic Address Detect mode is disabled
U1STAbits.ADM_EN = 0;
// UTXISEL<1:0>: TX Interrupt Mode Selection bits : 00 = Interrupt is generated and asserted while the transmit buffer contains at least one empty space
U1STAbits.UTXISEL1 = 0;
U1STAbits.UTXISEL0 = 0;
// UTXINV: Transmit Polarity Inversion bit : 0 = UxTX Idle state is ‘1’ (with IrDA disbled)
U1STAbits.UTXINV = 0;
// URXEN: Receiver Enable bit : 1 = UARTx receiver is enabled. UxRX pin is controlled by UARTx (if ON = 1)
U1STAbits.URXEN = 1;
// UTXBRK: Transmit Break bit : 0 = Break transmission is disabled or completed
U1STAbits.UTXBRK = 0;
// URXISEL<1:0>: Receive Interrupt Mode Selection bit : 00 = Interrupt flag bit is asserted while receive buffer is not empty (i.e., has at least 1 data character)
U1STAbits.URXISEL1 = 0;
U1STAbits.URXISEL0 = 0;
// ADDEN: Address Character Detect bit (bit 8 of received data = 1) : 0 = Address Detect mode is disabled
U1STAbits.ADDEN = 0;
// Baud Rate Calculation :
// FPB = 10MHz ; Desired Baud Rate = 9600 bauds
// => U1BRG = FPB/(16*BaudRate)-1 = 64 (error = 0,16%)
U1BRG = 64;
// Enable UART RX interrupts
//IEC1bits.U1RXIE = 1;
// Enable UART
// ON: UARTx Enable bit : 1 = UARTx is enabled. UARTx pins are controlled by UARTx as defined by the UEN<1:0> and UTXEN control bits.
U1MODEbits.ON = 1;
// UTXEN: Transmit Enable bit : 1 = UARTx transmitter is enabled. UxTX pin is controlled by UARTx (if ON = 1).
U1STAbits.UTXEN = 1;
}
For the moment I tried reading like this, in the while(1) loop, without success :
while (1)
{
uint8_t rxbyte[8];
bool b;
//if (U1STAbits.URXDA == 1)
while(!U1STAbits.URXDA);
rxbyte[0] = U1RXREG;
rxbyte[1] = U1RXREG;
rxbyte[2] = U1RXREG;
rxbyte[3] = U1RXREG;
rxbyte[4] = U1RXREG;
rxbyte[5] = U1RXREG;
rxbyte[6] = U1RXREG;
rxbyte[7] = U1RXREG;
sprintf(s, "I received : %u %u %u %u %u %u %u %u\n\r", rxbyte[0], rxbyte[1], rxbyte[2], rxbyte[3], rxbyte[4], rxbyte[5], rxbyte[6], rxbyte[7]);
myPrint(s);
IFS1bits.U1RXIF = 0;
}
The 8 bytes in rxbytes[] are always the same. I tried to clear the RX interrupt flag between the reads, reading URXDA also between the reads, add a delay, still no success, I still have to wait for 8 incoming bytes to access the first one.
Thanx in advance for your help !
Best regards.
Eric
I finally found the solution : I had a double configuration, one by MCC and one by myself, and it seems that having the interruptions activated caused this. Now I switched the interrupts off and I simply poll URXDA, and everything works fine.
Sorry for bothering you guys !
You can use your original method too. The problem with your While(1) loop is that you check if there is "at least 1 byte in the hardware Rx buffer" ( U1STAbits.URXDA tells you as soon as 1 byte is availlable ). When 1 byte is availlable, then you read 8 bytes inside the loop... so of course you will get 8 identical bytes when there is only 1 byte in the buffer.
Does anyone know if it's possible to change the units display for uploaded files? I uploaded a file that is 600 MB, and the display says 0.6 Gib... It's not real user friendly. I've checked the instructions on the website, and cannot find anything beyond how to change the filesizeBase from 1000 to 1024.
I had a similar need because I had to show the units always on KB. I found a function in dropzone.js called filesize and I just overwritten it by the next one on my own code:
Dropzone.prototype.filesize = function(size) {
var selectedSize = Math.round(size / 1024);
return "<strong>" + selectedSize + "</strong> KB";
};
I think you have to overwrite the same function but adapt it for your needs.
I hope is still useful for you.
This is more similar to the existing filesize function included in Dropzone (except more verbose).
Dropzone.prototype.filesize = function (bytes) {
let selectedSize = 0;
let selectedUnit = 'b';
let units = ['kb', 'mb', 'gb', 'tb'];
if (Math.abs(bytes) < this.options.filesizeBase) {
selectedSize = bytes;
} else {
var u = -1;
do {
bytes /= this.options.filesizeBase;
++u;
} while (Math.abs(bytes) >= this.options.filesizeBase && u < units.length - 1);
selectedSize = bytes.toFixed(1);
selectedUnit = units[u];
}
return `<strong>${selectedSize}</strong> ${this.options.dictFileSizeUnits[selectedUnit]}`;
}
Example:
339700 bytes -> 339.7 KB (instead of 0.3 MB which is what Dropzone returns by default)
Source: https://stackoverflow.com/a/14919494/1922696
This piece of code works for me:
Dropzone.prototype.filesize = function (bytes) {
let selectedSize = 0;
let units = ['B', 'KB', 'MB', 'GB', 'TB'];
var size = bytes;
while (size > 1000) {
selectedSize = selectedSize + 1;
size = size/1000;
}
return "<strong>" + Math.trunc(size * 100)/100 + "</strong> " + units[selectedSize];
}
I'm dividing by 1000, because otherwise I get 1010 KB, instead of 1.01 MB.
The problem is a bowling system which the wording of the question says:
The application will randomly choose the number of pins knocked down,
with a double chance to numbers 7,8,9 and 10.
The way I implemented is something like
So I came up with something like this:
pins = [0,0,0,0,0,0,0,0,0,0] // (1 for pin knocked down / 0 for pin standing)
for(i=0; i<pins.length; i++)
if(pins[i]==0): //pin isn't already down
if(i<6)
if(random(0~100) < 50):
pins[i] = 1 //knock down
else
if(random(0~100) < 66):
pins[i] = 1 //knock down
ex: [0,1,0,1,0,0,1,1,1,1] // 6 pins knocked down.
So I was just doing a probability of 1/2 to the pins 0-6 and 2/3 to pins 7-9
and I just sum all elements off the array to know home many pins have been dropped.
But I realized that I never get a strike nor a zero, so I start to wondering if I'm doing this wrong.
Let's say that that all pins have equal chance, and I could just do pinsDropped = random(0,10) and I would eventually get strikes (10) 9% chance and 0 pins dropped as well. But I have 4 pins that have double the chance of being dropped, I should have getting strikes more often.
What I'm doing wrong?
Update:
Yes, I suck at probability. After talking to a other people, one pointed to me that I also suck reading questions wording. I completely misinterpreted the problem. When it says randomly choose the number of pins knocked down and double the chance to numbers 7,8,9,10.
It means that I'm more likely to knock down 10 pins than 6 pins.
7 pins, 8 pins, 9 pins and 10 pins.
Not pin 7, pin 8, pin 9 and pin 10.
I'm totally frustrated about my stupidness.
So I overcomplicated this a lot,
function try(pins, prob) {
if (prob > pins)
prob = pins;
aleat = mt_rand(0, pins+prob);
if (aleat > pins)
aleat -= prob;
return aleat;
}
The application will randomly choose the number of pins knocked down,
with a double chance to the pins 7,8,9 and 10.
Problem Description:
We have 10 pins in total.
pins 7,8,9 and 10 have double chance.
we've (6 * 1) + (4 * 2) = 6 + 8 = 14 chances in total.
A = { 1, 2, 3, 4, 5, 6 } ; a is in A
B = { 7, 8, 9, 10 } ; b is in B
P(a) = 1/14
P(b) = 2P(a) = 2/14 = 1/7
Proposed Solution (Java):
Code:
ArrayList<byte> pins = new ArrayList<byte>();
pins.addAll({1,2,3,4,5,6,7,8,9,10});
while (pins.size() > 0)
{
/** pre-trial **/
PinsExperiment.trial(pins);
/** post-trial **/
}
Classes:
class PinsExperiment
{
public static byte getChances(ArrayList<byte> pins)
{
byte c = 0;
for (byte b : pins)
{
if (b <= 6) c += 1;
else c += 2;
}
return c;
}
public static void trial(ArrayList<byte> pins)
{
byte chances = getChances(pins);
byte r = Math.ceil(Math.random(0,chances));
byte n = 0;
for (byte b : pins) if (b <= 6) n++;
if (r <= n) pins.remove(pins.get(r-1));
else pins.remove(pins.get(((r-n)/2)-1)+n);
}
}
Simple answer:
def randomChoose():
x = randint(1,14);
if x<=7:
return x;
else:
return 6+ (x-5)/2;