Перейти к содержанию
    

Использовал доработанную библиотеку от

" http://stm32f4-discovery.net/2014/07/libra...32f4xx-devices/ "

Перед этим через STM32CubeL4 создал проект для SPI1 (под Кейл).

Соответственно в скачанной библиотеке поправил вызовы функций передачи и приема байтов по SPI через HAL-драйверы.

В результате с RC522 нормально читаю все регистры. Их содержимое соответствует тому, что должно быть после сброса по умолчанию.

Потом провожу инициализацию и вижу правильное их изменение .

Антенна включается и поле видно даже петлей.

После этого проводится непрерывный запрос карты командой 0х26 (функция из библиотеки TM_MFRC522_Check(CardID)).

В поле виден байт запроса и потом байт остановки (функция TM_MFRC522_Halt())

 

Независимо от присутствия/отсутствия карты ничего не происходит (всегда status = MI_ERR).

Осциллографом из ответов ничего не обнаруживается ни в поле, ни на ножках RC522.

 

Была попытка продублировать ответы карты внутри RC522 на ножку MFOUT (установкой регистра TxSelReg/0х16 байтом 0х17), но на этой ножке всегда 3-е состояние почему-то.

Всё это проверено на 2 считывателях, 3 картах и 2 брелках (из комплекта).

 

Таким образом нахожусь в недоумении.

Я что-то не включаю? Хотя по той библиотеке я делаю тот же Init.

Могут ли быть два считывателя подряд неисправными?

MFRC522 подключен к SPI1 STM32L476

PE15 - MOSI

PE14 - MISO

PE13 - SCK

PE12 - SS

PE10 - RST

 

При включение сначала сигнал RST выставляется в "1".

Потом инициализация:

void TM_MFRC522_Init(void) 
   {
      
   TM_MFRC522_Reset();
   TM_MFRC522_WriteRegister(MFRC522_REG_T_MODE, 0x8D);
   TM_MFRC522_WriteRegister(MFRC522_REG_T_PRESCALER, 0x3E);
   TM_MFRC522_WriteRegister(MFRC522_REG_T_RELOAD_L, 30);           
   TM_MFRC522_WriteRegister(MFRC522_REG_T_RELOAD_H, 0);
   TM_MFRC522_WriteRegister(MFRC522_REG_TX_SELL, 0x15);
   
   TM_MFRC522_WriteRegister(MFRC522_REG_TX_AUTO, 0x40);
   TM_MFRC522_WriteRegister(MFRC522_REG_MODE, 0x3D);

      
    TM_MFRC522_AntennaOn();      //Open the antenna
      
   }

Привожу содержимое регистров

 

Далее показаны первые 31 регистр перед запросом и после запроса

(PICC_REQIDL=0х0С)

Рег. - Иниц. - Запрос+Стоп

0x01 - 0x20 - 0x0C
0x02 - 0x80 - 0xF7
0x03 - 0x00 - 0x00
0x04 - 0x14 - 0x44
0x05 - 0x00 - 0x04
0x06 - 0x00 - 0x00 
0x07 - 0x29 - 0x39
0x08 - 0x00 - 0x05
0x09 - 0x26 - 0x00
0x0A - 0x00 - 0x00
0x0B - 0x08 - 0x08
0x0C - 0x10 - 0x10
0x0D - 0x00 - 0x04
0x0E - 0xA0 - 0xA0
0x0F - 0x00 <-
0x10 - 0x00 <-
0x11 - 0x3D <-
0x12 - 0x00 <-
0x13 - 0x00 <-
0x14 - 0x83 <-
0x15 - 0x40 <-
0x16 - 0x15 <-
0x17 - 0x84 <-
0x18 - 0x84 <-
0x19 - 0x4D <-
0x1A - 0x00 <-
0x1B - 0x00 <-
0x1C - 0x62 <-
0x1D - 0x00 <-
0x1E - 0x00 <-
0x1F - 0xEB <-

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Была попытка продублировать ответы карты внутри RC522 на ножку MFOUT

(установкой регистра TxSelReg/0х16 байтом 0х17), но на этой ножке всегда 3-е состояние почему-то.

Если это китайская плата, то там не подано питание, чтоб работал MFOUT.

Запросы и ответы хорошо видны осциллографом на конденсаторах в районе антенны.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Довелось мне запускать этот китайский считыватель, попил он мне тогда крови но запустился. Он время от времени наглухо зависает, лечит периодическим передергиванием ресета. Вот исходники из проекта. Кстати да, дрйвер взят по той ссылке, что привел ТС. В программе я считывал метки 5-ю считывателями и если они совпадали с запрограммированными занчениями открывался замок. Код рабочий, может поможет.

app.rar

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Он время от времени наглухо зависает

Не замечал такого. DS утверждает, что ревизия 2 стабильнее 1.

Кста, на моей китайской плате ID чипа равен 0x90, а такого быть не должно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может и от ревизии зависит, но у меня зависал намертво. Переставала даже дергаться нога IRQ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может и от ревизии зависит, но у меня зависал намертво. Переставала даже дергаться нога IRQ.

Еще замечу, что китайская плата у меня изначально была неисправна.

Перепаял микросхему (сдул-помыл-поставил на место) и все заработало.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я очень хочу надеяться, что у меня эта плата (две платы!) неисправна. Но всё же две подряд.

Во всей истории волнует только вопрос - КАК? Как определить, что плата дохлая?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну вот проверил данный экземпляр считывателя с Ардуино Уно. Всё прекрасно, все карты видит.

Что дальше?

Начинаю сравнивать осциллографом.

В работающем варианте в посылке вижу 6 импульсов (нули в поле).

У меня - на 2 импульса больше.

Хотя и там и там байт запроса один тот же - 0х26.

Что-то с количеством бит не так.

Всё излазил. Инициализация одинакова, записываемое в регистры то же по содержанию и по порядку.

Но разница видна отчетливо. Причем начало одинаково. У меня откуда берутся еще два нуля в поле.

Изменено пользователем serglg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В работающем варианте в посылке вижу 6 импульсов (нули в поле).

У меня - на 2 импульса больше.

Должно быть 7 бит.

Длина посылки при отправке и приеме см. в регистре BitFramingReg (0x0D).

В ISO/IEC 14443-3 есть таблица 2 - там описаны команды формата Short frame (7 битные).

0x26 = REQA - семибитная.

Как правильно считать биты с учетом стартовых, стоповых и контрольных см. ISO/IEC 14443-2

14443_3.pdf

14443_2.pdf

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

весьма полезно, спасибо. Вот только не пойму почему у меня больше 7 бит. Ведь всё один к одному с того источника, что указал выше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

весьма полезно, спасибо. Вот только не пойму почему у меня больше 7 бит. Ведь всё один к одному с того источника, что указал выше.

Тогда ваш код в студию.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В основном цикле у меня вызывается:

STAT = TM_MFRC522_Check(CardID);

В том файле mfrc522.c, где функция шапка:

/**	
* |----------------------------------------------------------------------
* | Copyright © Tilen Majerle, 2014
* | 
* | This program is free software: you can redistribute it and/or modify
* | it under the terms of the GNU General Public License as published by
* | the Free Software Foundation, either version 3 of the License, or
* | any later version.
* |  
* | This program is distributed in the hope that it will be useful,
* | but WITHOUT ANY WARRANTY; without even the implied warranty of
* | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* | GNU General Public License for more details.
* | 
* | You should have received a copy of the GNU General Public License
* | along with this program.  If not, see <http://www.gnu.org/licenses/>.
* |----------------------------------------------------------------------
*/

/**
* Status enumeration
*
* Used with most functions
*/

#include <stdio.h>

typedef enum 
{
MI_OK = 0,
MI_NOTAGERR,
MI_ERR
}	TM_MFRC522_Status_t;


#define MFRC522_CS_LOW					MFRC522_CS_PORT->BSRRH = MFRC522_CS_PIN;
#define MFRC522_CS_HIGH					MFRC522_CS_PORT->BSRRL = MFRC522_CS_PIN;

/* MFRC522 Commands */
#define PCD_IDLE						0x00   //NO action; Cancel the current command
#define PCD_AUTHENT						0x0E   //Authentication Key
#define PCD_RECEIVE						0x08   //Receive Data
#define PCD_TRANSMIT					0x04   //Transmit data
#define PCD_TRANSCEIVE					0x0C   //Transmit and receive data,
#define PCD_RESETPHASE					0x0F   //Reset
#define PCD_CALCCRC						0x03   //CRC Calculate

/* Mifare_One card command word */
#define PICC_REQIDL						0x26   // find the antenna area does not enter hibernation
#define PICC_REQALL						0x52   // find all the cards antenna area
#define PICC_ANTICOLL					0x93   // anti-collision
#define PICC_SElECTTAG					0x93   // election card
#define PICC_AUTHENT1A					0x60   // authentication key A
#define PICC_AUTHENT1B					0x61   // authentication key B
#define PICC_READ						0x30   // Read Block
#define PICC_WRITE						0xA0   // write block
#define PICC_DECREMENT					0xC0   // debit
#define PICC_INCREMENT					0xC1   // recharge
#define PICC_RESTORE					0xC2   // transfer block data to the buffer
#define PICC_TRANSFER					0xB0   // save the data in the buffer
#define PICC_HALT						0x50   // Sleep

/* MFRC522 Registers */
//Page 0: Command and Status
#define MFRC522_REG_RESERVED00			0x00    
#define MFRC522_REG_COMMAND				0x01    
#define MFRC522_REG_COMM_IE_N			0x02    
#define MFRC522_REG_DIV1_EN				0x03    
#define MFRC522_REG_COMM_IRQ			0x04    
#define MFRC522_REG_DIV_IRQ				0x05
#define MFRC522_REG_ERROR				0x06    
#define MFRC522_REG_STATUS1				0x07    
#define MFRC522_REG_STATUS2				0x08    
#define MFRC522_REG_FIFO_DATA			0x09
#define MFRC522_REG_FIFO_LEVEL			0x0A
#define MFRC522_REG_WATER_LEVEL			0x0B
#define MFRC522_REG_CONTROL				0x0C
#define MFRC522_REG_BIT_FRAMING			0x0D
#define MFRC522_REG_COLL				0x0E
#define MFRC522_REG_RESERVED01			0x0F
//Page 1: Command 
#define MFRC522_REG_RESERVED10			0x10
#define MFRC522_REG_MODE				0x11
#define MFRC522_REG_TX_MODE				0x12
#define MFRC522_REG_RX_MODE				0x13
#define MFRC522_REG_TX_CONTROL			0x14
#define MFRC522_REG_TX_AUTO				0x15
#define MFRC522_REG_TX_SELL				0x16
#define MFRC522_REG_RX_SELL				0x17
#define MFRC522_REG_RX_THRESHOLD		0x18
#define MFRC522_REG_DEMOD				0x19
#define MFRC522_REG_RESERVED11			0x1A
#define MFRC522_REG_RESERVED12			0x1B
#define MFRC522_REG_MIFARE				0x1C
#define MFRC522_REG_RESERVED13			0x1D
#define MFRC522_REG_RESERVED14			0x1E
#define MFRC522_REG_SERIALSPEED			0x1F
//Page 2: CFG    
#define MFRC522_REG_RESERVED20			0x20  
#define MFRC522_REG_CRC_RESULT_M		0x21
#define MFRC522_REG_CRC_RESULT_L		0x22
#define MFRC522_REG_RESERVED21			0x23
#define MFRC522_REG_MOD_WIDTH			0x24
#define MFRC522_REG_RESERVED22			0x25
#define MFRC522_REG_RF_CFG				0x26
#define MFRC522_REG_GS_N				0x27
#define MFRC522_REG_CWGS_PREG			0x28
#define MFRC522_REG__MODGS_PREG			0x29
#define MFRC522_REG_T_MODE				0x2A
#define MFRC522_REG_T_PRESCALER			0x2B
#define MFRC522_REG_T_RELOAD_H			0x2C
#define MFRC522_REG_T_RELOAD_L			0x2D
#define MFRC522_REG_T_COUNTER_VALUE_H	0x2E
#define MFRC522_REG_T_COUNTER_VALUE_L	0x2F
//Page 3:TestRegister 
#define MFRC522_REG_RESERVED30			0x30
#define MFRC522_REG_TEST_SEL1			0x31
#define MFRC522_REG_TEST_SEL2			0x32
#define MFRC522_REG_TEST_PIN_EN			0x33
#define MFRC522_REG_TEST_PIN_VALUE		0x34
#define MFRC522_REG_TEST_BUS			0x35
#define MFRC522_REG_AUTO_TEST			0x36
#define MFRC522_REG_VERSION				0x37
#define MFRC522_REG_ANALOG_TEST			0x38
#define MFRC522_REG_TEST_ADC1			0x39  
#define MFRC522_REG_TEST_ADC2			0x3A   
#define MFRC522_REG_TEST_ADC0			0x3B   
#define MFRC522_REG_RESERVED31			0x3C   
#define MFRC522_REG_RESERVED32			0x3D
#define MFRC522_REG_RESERVED33			0x3E   
#define MFRC522_REG_RESERVED34			0x3F
//Dummy byte
#define MFRC522_DUMMY					0x00

#define MFRC522_MAX_LEN					16


/**
* Private functions
*/
extern TM_MFRC522_Status_t TM_MFRC522_Check(uint8_t* id);


extern void TM_MFRC522_Test(void);
extern void TM_MFRC522_InitPins(void);
extern void TM_MFRC522_WriteRegister(uint8_t addr, uint8_t val);
extern uint8_t TM_MFRC522_ReadRegister(uint8_t addr);
extern TM_MFRC522_Status_t TM_MFRC522_ToCard(uint8_t command, uint8_t* sendData, uint8_t sendLen, uint8_t* backData, uint16_t* backLen);
extern TM_MFRC522_Status_t TM_MFRC522_Request(uint8_t reqMode, uint8_t* TagType);
extern TM_MFRC522_Status_t TM_MFRC522_Anticoll(uint8_t* serNum);
extern void TM_MFRC522_SetBitMask(uint8_t reg, uint8_t mask);
extern void TM_MFRC522_ClearBitMask(uint8_t reg, uint8_t mask);
extern void TM_MFRC522_AntennaOn(void);
extern void TM_MFRC522_AntennaOff(void);
extern void TM_MFRC522_Reset(void);
extern void TM_MFRC522_Halt(void);
extern void TM_MFRC522_CalculateCRC(uint8_t* pIndata, uint8_t len, uint8_t* pOutData);
void *memcpy(void *dst, const void *src, size_t len);

	uint8_t OTVRC522[2];
	uint8_t BUFRC522[48];
	uint8_t BUFWR522[48];
	uint8_t ZAPRC522[2];


Сама функция:

TM_MFRC522_Status_t TM_MFRC522_Check(uint8_t* id) 
{
TM_MFRC522_Status_t status;
//Find cards, return card type
status = TM_MFRC522_Request(PICC_REQIDL, id);	
if (status == MI_OK) 
	{
	//Card detected
	//Anti-collision, return card serial number 4 bytes
	status = TM_MFRC522_Anticoll(id);	

	}


//TM_MFRC522_Halt();			//Command card into hibernation 

HAL_Delay(20);


return status;
}


Запрос:

TM_MFRC522_Status_t TM_MFRC522_Request(uint8_t reqMode, uint8_t* TagType) 
{
TM_MFRC522_Status_t status;  
uint16_t backBits;			//The received data bits

TM_MFRC522_WriteRegister(MFRC522_REG_BIT_FRAMING, 0x07);		//TxLastBists = BitFramingReg[2..0]	???

TagType[0] = reqMode;
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8, GPIO_PIN_RESET);

status = TM_MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);

if ((status != MI_OK) || (backBits != 0x10)) 
	{    
	status = MI_ERR;
	}

return status;
}

Ну и самая тяжелая часть:

TM_MFRC522_Status_t TM_MFRC522_ToCard(uint8_t command, uint8_t* sendData, uint8_t sendLen, uint8_t* backData, uint16_t* backLen) 
{
TM_MFRC522_Status_t status = MI_ERR;
uint8_t irqEn = 0x00;
uint8_t waitIRq = 0x00;
uint8_t lastBits;
uint8_t n;
uint16_t i;

switch (command) 
	{
	case PCD_AUTHENT: 
		{
		irqEn = 0x12;
		waitIRq = 0x10;
		break;
		}
	case PCD_TRANSCEIVE: 
		{
		irqEn = 0x77;
		waitIRq = 0x30;
		break;
		}
		default:
		break;
	}


TM_MFRC522_WriteRegister(MFRC522_REG_COMM_IE_N, irqEn | 0x80);
TM_MFRC522_ClearBitMask(MFRC522_REG_COMM_IRQ, 0x80);
TM_MFRC522_SetBitMask(MFRC522_REG_FIFO_LEVEL, 0x80);

TM_MFRC522_WriteRegister(MFRC522_REG_COMMAND, PCD_IDLE);

//Writing data to the FIFO
for (i = 0; i < sendLen; i++)
		{   
	TM_MFRC522_WriteRegister(MFRC522_REG_FIFO_DATA, sendData[i]);    
		}

//Execute the command
TM_MFRC522_WriteRegister(MFRC522_REG_COMMAND, command);
if (command == PCD_TRANSCEIVE) 
	{    
	TM_MFRC522_SetBitMask(MFRC522_REG_BIT_FRAMING, 0x80);		//StartSend=1,transmission of data starts  
	}   

//Waiting to receive data to complete
i = 2000;	//i according to the clock frequency adjustment, the operator M1 card maximum waiting time 25ms???
do 
	{
	//CommIrqReg[7..0]
	//Set1 TxIRq RxIRq IdleIRq HiAlerIRq LoAlertIRq ErrIRq TimerIRq
	n = TM_MFRC522_ReadRegister(MFRC522_REG_COMM_IRQ);
	i--;
	} 
	while ((i!=0) && !(n&0x01) && !(n&waitIRq));

TM_MFRC522_ClearBitMask(MFRC522_REG_BIT_FRAMING, 0x80);			//StartSend=0
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_8, GPIO_PIN_SET);

if (i != 0)  
	{
		if (!(TM_MFRC522_ReadRegister(MFRC522_REG_ERROR) & 0x1B)) 
		{
		status = MI_OK;
		if (n & irqEn & 0x01) 
			{   
			status = MI_NOTAGERR;			
			}

			if (command == PCD_TRANSCEIVE) 
			{
			n = TM_MFRC522_ReadRegister(MFRC522_REG_FIFO_LEVEL);

			lastBits = TM_MFRC522_ReadRegister(MFRC522_REG_CONTROL) & 0x07;
				VREMUART[0]=TM_MFRC522_ReadRegister(MFRC522_REG_COMMAND);
			if (lastBits) 
					{   
				*backLen = (n - 1) * 8 + lastBits;   
					} 
			else 
			{   
				*backLen = n * 8;   
			}

			if (n == 0) 
				{   
				n = 1;    
				}
			if (n > MFRC522_MAX_LEN) 
				{   
				n = MFRC522_MAX_LEN;   
				}

			//Reading the received data in FIFO
			for (i = 0; i < n; i++) 
				{   
				backData[i] = TM_MFRC522_ReadRegister(MFRC522_REG_FIFO_DATA);    
				}
			}
		} 
		else 
			{   
		status = MI_ERR;  
			}
}

return status;
}

Чтение/запись регистров через HAL-драйверы по SPI не привожу. Много раз убеждался, что там всё работает.

Изменено пользователем IgorKossak
[codebox] для длинного кода. [code]-для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

TM_MFRC522_Status_t TM_MFRC522_Request(uint8_t reqMode, uint8_t* TagType)

{

...

TM_MFRC522_WriteRegister(MFRC522_REG_BIT_FRAMING, 0x07); //TxLastBists = BitFramingReg[2..0] ???

...

status = TM_MFRC522_ToCard(PCD_TRANSCEIVE, TagType, 1, TagType, &backBits);

...

}

 

TM_MFRC522_Status_t TM_MFRC522_ToCard(uint8_t command, uint8_t* sendData, uint8_t sendLen, uint8_t* backData, uint16_t* backLen)

{

...

if (command == PCD_TRANSCEIVE)

{

TM_MFRC522_SetBitMask(MFRC522_REG_BIT_FRAMING, 0x80); //StartSend=1,transmission of data starts

}

...

}

Сначала записываете 0x07 (TxLastBits=7), а затем стартуете с 0x80 (TxLastBits=0, что соответствует 8 битам).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сначала записываете 0x07 (TxLastBits=7), а затем стартуете с 0x80 (TxLastBits=0, что соответствует 8 битам).

 

Но как же? Там же функция установки бита. Т.е. вроде только старший бит встает в единицу. Младшие (TxLastBits) остаются (или должны оставаться) так же - 7.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но как же? Там же функция установки бита. Т.е. вроде только старший бит встает в единицу. Младшие (TxLastBits) остаются (или должны оставаться) так же - 7.

Точно. Проглядел.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...