serglg 0 19 июля, 2016 Опубликовано 19 июля, 2016 (изменено) · Жалоба Использовал доработанную библиотеку от " 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 <- Изменено 19 июля, 2016 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 10 19 июля, 2016 Опубликовано 19 июля, 2016 · Жалоба Была попытка продублировать ответы карты внутри RC522 на ножку MFOUT (установкой регистра TxSelReg/0х16 байтом 0х17), но на этой ножке всегда 3-е состояние почему-то. Если это китайская плата, то там не подано питание, чтоб работал MFOUT. Запросы и ответы хорошо видны осциллографом на конденсаторах в районе антенны. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yanvasilij 0 20 июля, 2016 Опубликовано 20 июля, 2016 · Жалоба Довелось мне запускать этот китайский считыватель, попил он мне тогда крови но запустился. Он время от времени наглухо зависает, лечит периодическим передергиванием ресета. Вот исходники из проекта. Кстати да, дрйвер взят по той ссылке, что привел ТС. В программе я считывал метки 5-ю считывателями и если они совпадали с запрограммированными занчениями открывался замок. Код рабочий, может поможет. app.rar Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 10 20 июля, 2016 Опубликовано 20 июля, 2016 · Жалоба Он время от времени наглухо зависает Не замечал такого. DS утверждает, что ревизия 2 стабильнее 1. Кста, на моей китайской плате ID чипа равен 0x90, а такого быть не должно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
yanvasilij 0 20 июля, 2016 Опубликовано 20 июля, 2016 · Жалоба Может и от ревизии зависит, но у меня зависал намертво. Переставала даже дергаться нога IRQ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 10 20 июля, 2016 Опубликовано 20 июля, 2016 · Жалоба Может и от ревизии зависит, но у меня зависал намертво. Переставала даже дергаться нога IRQ. Еще замечу, что китайская плата у меня изначально была неисправна. Перепаял микросхему (сдул-помыл-поставил на место) и все заработало. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
serglg 0 20 июля, 2016 Опубликовано 20 июля, 2016 · Жалоба Я очень хочу надеяться, что у меня эта плата (две платы!) неисправна. Но всё же две подряд. Во всей истории волнует только вопрос - КАК? Как определить, что плата дохлая? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
serglg 0 25 июля, 2016 Опубликовано 25 июля, 2016 (изменено) · Жалоба Ну вот проверил данный экземпляр считывателя с Ардуино Уно. Всё прекрасно, все карты видит. Что дальше? Начинаю сравнивать осциллографом. В работающем варианте в посылке вижу 6 импульсов (нули в поле). У меня - на 2 импульса больше. Хотя и там и там байт запроса один тот же - 0х26. Что-то с количеством бит не так. Всё излазил. Инициализация одинакова, записываемое в регистры то же по содержанию и по порядку. Но разница видна отчетливо. Причем начало одинаково. У меня откуда берутся еще два нуля в поле. Изменено 25 июля, 2016 пользователем serglg Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 10 25 июля, 2016 Опубликовано 25 июля, 2016 · Жалоба В работающем варианте в посылке вижу 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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
serglg 0 26 июля, 2016 Опубликовано 26 июля, 2016 · Жалоба весьма полезно, спасибо. Вот только не пойму почему у меня больше 7 бит. Ведь всё один к одному с того источника, что указал выше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 10 26 июля, 2016 Опубликовано 26 июля, 2016 · Жалоба весьма полезно, спасибо. Вот только не пойму почему у меня больше 7 бит. Ведь всё один к одному с того источника, что указал выше. Тогда ваш код в студию. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
serglg 0 26 июля, 2016 Опубликовано 26 июля, 2016 (изменено) · Жалоба В основном цикле у меня вызывается: 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 не привожу. Много раз убеждался, что там всё работает. Изменено 26 июля, 2016 пользователем IgorKossak [codebox] для длинного кода. [code]-для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 10 26 июля, 2016 Опубликовано 26 июля, 2016 · Жалоба 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 битам). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
serglg 0 26 июля, 2016 Опубликовано 26 июля, 2016 · Жалоба Сначала записываете 0x07 (TxLastBits=7), а затем стартуете с 0x80 (TxLastBits=0, что соответствует 8 битам). Но как же? Там же функция установки бита. Т.е. вроде только старший бит встает в единицу. Младшие (TxLastBits) остаются (или должны оставаться) так же - 7. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 10 26 июля, 2016 Опубликовано 26 июля, 2016 · Жалоба Но как же? Там же функция установки бита. Т.е. вроде только старший бит встает в единицу. Младшие (TxLastBits) остаются (или должны оставаться) так же - 7. Точно. Проглядел. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться