QAQ ==!

Dependencies:   mbed QEI-1 nRF24L01P xiugai

Committer:
AlexQian
Date:
Sat Dec 14 05:45:16 2019 +0000
Revision:
15:934289377f7a
Parent:
9:d03b1af2b8d8
Balance_Car;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
zhangyx 9:d03b1af2b8d8 1 ////////////////////////////////////////////////////////////////////////////////
zhangyx 9:d03b1af2b8d8 2 // pn532 hsu interface for mbed platform
zhangyx 9:d03b1af2b8d8 3 //
zhangyx 9:d03b1af2b8d8 4 // by dotnfc@163.com
zhangyx 9:d03b1af2b8d8 5 // 2016/09/10 18:16:00
zhangyx 9:d03b1af2b8d8 6
zhangyx 9:d03b1af2b8d8 7 #include "PN532_HSU.h"
zhangyx 9:d03b1af2b8d8 8 #include "PN532_debug.h"
zhangyx 9:d03b1af2b8d8 9
zhangyx 9:d03b1af2b8d8 10
zhangyx 9:d03b1af2b8d8 11 PN532_HSU::PN532_HSU(HardwareSerial &serial)
zhangyx 9:d03b1af2b8d8 12 {
zhangyx 9:d03b1af2b8d8 13 _serial = &serial;
zhangyx 9:d03b1af2b8d8 14 command = 0;
zhangyx 9:d03b1af2b8d8 15 }
zhangyx 9:d03b1af2b8d8 16
zhangyx 9:d03b1af2b8d8 17 void PN532_HSU::begin()
zhangyx 9:d03b1af2b8d8 18 {
zhangyx 9:d03b1af2b8d8 19 _serial->baud(115200);
zhangyx 9:d03b1af2b8d8 20 }
zhangyx 9:d03b1af2b8d8 21
zhangyx 9:d03b1af2b8d8 22 void PN532_HSU::wakeup()
zhangyx 9:d03b1af2b8d8 23 {
zhangyx 9:d03b1af2b8d8 24 const uint8_t wakeup_cmd[] = { 0x55, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x05, 0xFB, 0xD4, 0x14, 0x01, 0x00, 0x01, 0x16, 0x00 };
zhangyx 9:d03b1af2b8d8 25 _serial->write(wakeup_cmd, sizeof(wakeup_cmd));
zhangyx 9:d03b1af2b8d8 26
zhangyx 9:d03b1af2b8d8 27 delay (50);
zhangyx 9:d03b1af2b8d8 28
zhangyx 9:d03b1af2b8d8 29 /** dump serial buffer */
zhangyx 9:d03b1af2b8d8 30 if(_serial->readable()){
zhangyx 9:d03b1af2b8d8 31 DMSG("Dump sperial buffer: ");
zhangyx 9:d03b1af2b8d8 32 }
zhangyx 9:d03b1af2b8d8 33 while(_serial->readable()){
zhangyx 9:d03b1af2b8d8 34 uint8_t ret = _serial->getc();
zhangyx 9:d03b1af2b8d8 35 DMSG_HEX(ret);
zhangyx 9:d03b1af2b8d8 36 }
zhangyx 9:d03b1af2b8d8 37 DMSG("\n");
zhangyx 9:d03b1af2b8d8 38 }
zhangyx 9:d03b1af2b8d8 39
zhangyx 9:d03b1af2b8d8 40 int8_t PN532_HSU::writeCommand(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
zhangyx 9:d03b1af2b8d8 41 {
zhangyx 9:d03b1af2b8d8 42 /** dump serial buffer */
zhangyx 9:d03b1af2b8d8 43 if(_serial->readable()){
zhangyx 9:d03b1af2b8d8 44 DMSG("Dump sperial buffer: ");
zhangyx 9:d03b1af2b8d8 45 }
zhangyx 9:d03b1af2b8d8 46 while(_serial->readable()){
zhangyx 9:d03b1af2b8d8 47 uint8_t ret = _serial->getc();
zhangyx 9:d03b1af2b8d8 48 DMSG_HEX(ret);
zhangyx 9:d03b1af2b8d8 49 }
zhangyx 9:d03b1af2b8d8 50 DMSG("\n");
zhangyx 9:d03b1af2b8d8 51
zhangyx 9:d03b1af2b8d8 52 command = header[0];
zhangyx 9:d03b1af2b8d8 53
zhangyx 9:d03b1af2b8d8 54 _serial->write(PN532_PREAMBLE);
zhangyx 9:d03b1af2b8d8 55 _serial->write(PN532_STARTCODE1);
zhangyx 9:d03b1af2b8d8 56 _serial->write(PN532_STARTCODE2);
zhangyx 9:d03b1af2b8d8 57
zhangyx 9:d03b1af2b8d8 58 uint8_t length = hlen + blen + 1; // length of data field: TFI + DATA
zhangyx 9:d03b1af2b8d8 59 _serial->write(length);
zhangyx 9:d03b1af2b8d8 60 _serial->write(~length + 1); // checksum of length
zhangyx 9:d03b1af2b8d8 61
zhangyx 9:d03b1af2b8d8 62 _serial->write(PN532_HOSTTOPN532);
zhangyx 9:d03b1af2b8d8 63 uint8_t sum = PN532_HOSTTOPN532; // sum of TFI + DATA
zhangyx 9:d03b1af2b8d8 64
zhangyx 9:d03b1af2b8d8 65 DMSG("\nWrite: ");
zhangyx 9:d03b1af2b8d8 66
zhangyx 9:d03b1af2b8d8 67 _serial->write(header, hlen);
zhangyx 9:d03b1af2b8d8 68 for (uint8_t i = 0; i < hlen; i++) {
zhangyx 9:d03b1af2b8d8 69 sum += header[i];
zhangyx 9:d03b1af2b8d8 70
zhangyx 9:d03b1af2b8d8 71 DMSG_HEX(header[i]);
zhangyx 9:d03b1af2b8d8 72 }
zhangyx 9:d03b1af2b8d8 73
zhangyx 9:d03b1af2b8d8 74 _serial->write(body, blen);
zhangyx 9:d03b1af2b8d8 75 for (uint8_t i = 0; i < blen; i++) {
zhangyx 9:d03b1af2b8d8 76 sum += body[i];
zhangyx 9:d03b1af2b8d8 77
zhangyx 9:d03b1af2b8d8 78 DMSG_HEX(body[i]);
zhangyx 9:d03b1af2b8d8 79 }
zhangyx 9:d03b1af2b8d8 80
zhangyx 9:d03b1af2b8d8 81 uint8_t checksum = ~sum + 1; // checksum of TFI + DATA
zhangyx 9:d03b1af2b8d8 82 _serial->write(checksum);
zhangyx 9:d03b1af2b8d8 83 _serial->write(PN532_POSTAMBLE);
zhangyx 9:d03b1af2b8d8 84
zhangyx 9:d03b1af2b8d8 85 delay (50);
zhangyx 9:d03b1af2b8d8 86 return readAckFrame();
zhangyx 9:d03b1af2b8d8 87 }
zhangyx 9:d03b1af2b8d8 88
zhangyx 9:d03b1af2b8d8 89 int16_t PN532_HSU::readResponse(uint8_t buf[], uint8_t len, uint16_t timeout)
zhangyx 9:d03b1af2b8d8 90 {
zhangyx 9:d03b1af2b8d8 91 uint8_t tmp[3];
zhangyx 9:d03b1af2b8d8 92
zhangyx 9:d03b1af2b8d8 93 delay(100);
zhangyx 9:d03b1af2b8d8 94
zhangyx 9:d03b1af2b8d8 95 DMSG("\nRead: ");
zhangyx 9:d03b1af2b8d8 96
zhangyx 9:d03b1af2b8d8 97 /** Frame Preamble and Start Code */
zhangyx 9:d03b1af2b8d8 98 if(receive(tmp, 3, timeout)<=0){
zhangyx 9:d03b1af2b8d8 99 return PN532_TIMEOUT;
zhangyx 9:d03b1af2b8d8 100 }
zhangyx 9:d03b1af2b8d8 101 if(0 != tmp[0] || 0!= tmp[1] || 0xFF != tmp[2]){
zhangyx 9:d03b1af2b8d8 102 DMSG("Preamble error");
zhangyx 9:d03b1af2b8d8 103 return PN532_INVALID_FRAME;
zhangyx 9:d03b1af2b8d8 104 }
zhangyx 9:d03b1af2b8d8 105
zhangyx 9:d03b1af2b8d8 106 /** receive length and check */
zhangyx 9:d03b1af2b8d8 107 uint8_t length[2];
zhangyx 9:d03b1af2b8d8 108 if(receive(length, 2, timeout) <= 0){
zhangyx 9:d03b1af2b8d8 109 return PN532_TIMEOUT;
zhangyx 9:d03b1af2b8d8 110 }
zhangyx 9:d03b1af2b8d8 111 if( 0 != (uint8_t)(length[0] + length[1]) ){
zhangyx 9:d03b1af2b8d8 112 DMSG("Length error\n");
zhangyx 9:d03b1af2b8d8 113 return PN532_INVALID_FRAME;
zhangyx 9:d03b1af2b8d8 114 }
zhangyx 9:d03b1af2b8d8 115 length[0] -= 2;
zhangyx 9:d03b1af2b8d8 116 if( length[0] > len){
zhangyx 9:d03b1af2b8d8 117 return PN532_NO_SPACE;
zhangyx 9:d03b1af2b8d8 118 }
zhangyx 9:d03b1af2b8d8 119
zhangyx 9:d03b1af2b8d8 120 /** receive command byte */
zhangyx 9:d03b1af2b8d8 121 uint8_t cmd = command + 1; // response command
zhangyx 9:d03b1af2b8d8 122 if(receive(tmp, 2, timeout) <= 0){
zhangyx 9:d03b1af2b8d8 123 return PN532_TIMEOUT;
zhangyx 9:d03b1af2b8d8 124 }
zhangyx 9:d03b1af2b8d8 125 if( PN532_PN532TOHOST != tmp[0] || cmd != tmp[1]){
zhangyx 9:d03b1af2b8d8 126 DMSG("Command error\n");
zhangyx 9:d03b1af2b8d8 127 return PN532_INVALID_FRAME;
zhangyx 9:d03b1af2b8d8 128 }
zhangyx 9:d03b1af2b8d8 129
zhangyx 9:d03b1af2b8d8 130 if(receive(buf, length[0], timeout) != length[0]){
zhangyx 9:d03b1af2b8d8 131 return PN532_TIMEOUT;
zhangyx 9:d03b1af2b8d8 132 }
zhangyx 9:d03b1af2b8d8 133 uint8_t sum = PN532_PN532TOHOST + cmd;
zhangyx 9:d03b1af2b8d8 134 for(uint8_t i=0; i<length[0]; i++){
zhangyx 9:d03b1af2b8d8 135 sum += buf[i];
zhangyx 9:d03b1af2b8d8 136 }
zhangyx 9:d03b1af2b8d8 137
zhangyx 9:d03b1af2b8d8 138 /** checksum and postamble */
zhangyx 9:d03b1af2b8d8 139 if(receive(tmp, 2, timeout) <= 0){
zhangyx 9:d03b1af2b8d8 140 return PN532_TIMEOUT;
zhangyx 9:d03b1af2b8d8 141 }
zhangyx 9:d03b1af2b8d8 142 if( 0 != (uint8_t)(sum + tmp[0]) || 0 != tmp[1] ){
zhangyx 9:d03b1af2b8d8 143 DMSG("Checksum error\n");
zhangyx 9:d03b1af2b8d8 144 return PN532_INVALID_FRAME;
zhangyx 9:d03b1af2b8d8 145 }
zhangyx 9:d03b1af2b8d8 146
zhangyx 9:d03b1af2b8d8 147 DMSG ("\n");
zhangyx 9:d03b1af2b8d8 148 return length[0];
zhangyx 9:d03b1af2b8d8 149 }
zhangyx 9:d03b1af2b8d8 150
zhangyx 9:d03b1af2b8d8 151 int8_t PN532_HSU::readAckFrame()
zhangyx 9:d03b1af2b8d8 152 {
zhangyx 9:d03b1af2b8d8 153 const uint8_t PN532_ACK[] = {0, 0, 0xFF, 0, 0xFF, 0};
zhangyx 9:d03b1af2b8d8 154 uint8_t ackBuf[sizeof(PN532_ACK)];
zhangyx 9:d03b1af2b8d8 155
zhangyx 9:d03b1af2b8d8 156 delay(100);
zhangyx 9:d03b1af2b8d8 157
zhangyx 9:d03b1af2b8d8 158 DMSG("\nAck: ");
zhangyx 9:d03b1af2b8d8 159
zhangyx 9:d03b1af2b8d8 160 if( receive(ackBuf, sizeof(PN532_ACK), PN532_ACK_WAIT_TIME) <= 0 ){
zhangyx 9:d03b1af2b8d8 161 DMSG("Timeout\n");
zhangyx 9:d03b1af2b8d8 162 return PN532_TIMEOUT;
zhangyx 9:d03b1af2b8d8 163 }
zhangyx 9:d03b1af2b8d8 164
zhangyx 9:d03b1af2b8d8 165 if( memcmp(ackBuf, PN532_ACK, sizeof(PN532_ACK)) ){
zhangyx 9:d03b1af2b8d8 166 DMSG("Invalid\n");
zhangyx 9:d03b1af2b8d8 167 return PN532_INVALID_ACK;
zhangyx 9:d03b1af2b8d8 168 }
zhangyx 9:d03b1af2b8d8 169 return 0;
zhangyx 9:d03b1af2b8d8 170 }
zhangyx 9:d03b1af2b8d8 171
zhangyx 9:d03b1af2b8d8 172 /**
zhangyx 9:d03b1af2b8d8 173 @brief receive data .
zhangyx 9:d03b1af2b8d8 174 @param buf --> return value buffer.
zhangyx 9:d03b1af2b8d8 175 len --> length expect to receive.
zhangyx 9:d03b1af2b8d8 176 timeout --> time of reveiving
zhangyx 9:d03b1af2b8d8 177 @retval number of received bytes, 0 means no data received.
zhangyx 9:d03b1af2b8d8 178 */
zhangyx 9:d03b1af2b8d8 179 int8_t PN532_HSU::receive(uint8_t *buf, int len, uint16_t timeout)
zhangyx 9:d03b1af2b8d8 180 {
zhangyx 9:d03b1af2b8d8 181 int read_bytes = 0;
zhangyx 9:d03b1af2b8d8 182 int ret;
zhangyx 9:d03b1af2b8d8 183 Timer tmr_hsu;
zhangyx 9:d03b1af2b8d8 184 unsigned long start_millis;
zhangyx 9:d03b1af2b8d8 185
zhangyx 9:d03b1af2b8d8 186 tmr_hsu.start();
zhangyx 9:d03b1af2b8d8 187 while (read_bytes < len) {
zhangyx 9:d03b1af2b8d8 188 start_millis = tmr_hsu.read_ms(); // millis();
zhangyx 9:d03b1af2b8d8 189 do {
zhangyx 9:d03b1af2b8d8 190 ret = _serial->getc();
zhangyx 9:d03b1af2b8d8 191 if (ret >= 0) {
zhangyx 9:d03b1af2b8d8 192 break;
zhangyx 9:d03b1af2b8d8 193 }
zhangyx 9:d03b1af2b8d8 194 delay(10);
zhangyx 9:d03b1af2b8d8 195 } while((timeout == 0) || ((tmr_hsu.read_ms() /* millis() */ - start_millis ) < timeout));
zhangyx 9:d03b1af2b8d8 196
zhangyx 9:d03b1af2b8d8 197 if (ret < 0) {
zhangyx 9:d03b1af2b8d8 198 if(read_bytes){
zhangyx 9:d03b1af2b8d8 199 tmr_hsu.stop ();
zhangyx 9:d03b1af2b8d8 200 return read_bytes;
zhangyx 9:d03b1af2b8d8 201 }else{
zhangyx 9:d03b1af2b8d8 202 tmr_hsu.stop ();
zhangyx 9:d03b1af2b8d8 203 return PN532_TIMEOUT;
zhangyx 9:d03b1af2b8d8 204 }
zhangyx 9:d03b1af2b8d8 205 }
zhangyx 9:d03b1af2b8d8 206 buf[read_bytes] = (uint8_t)ret;
zhangyx 9:d03b1af2b8d8 207 DMSG_HEX(ret);
zhangyx 9:d03b1af2b8d8 208 read_bytes++;
zhangyx 9:d03b1af2b8d8 209 }
zhangyx 9:d03b1af2b8d8 210
zhangyx 9:d03b1af2b8d8 211 tmr_hsu.stop ();
zhangyx 9:d03b1af2b8d8 212 return read_bytes;
zhangyx 9:d03b1af2b8d8 213 }
zhangyx 9:d03b1af2b8d8 214