Microprocessor/Module

RFID(Reader control/Host Command)[20121011]

Dexter_- 2018. 12. 10. 09:56
728x90
반응형

RFID(Reader control/Host Command)




RFID 실습



HOST <- Reader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include <windows.h>
#include <stdio.h>
 
void text_out(unsigned char *);
unsigned short Emb_Crc(void *);
 
 
 
int main()
{
  unsigned char msg[] = { 0x0D,
              0x00,
              0x71,
              0x000x30,
              0x000x00,
              0x000x0A,
              0x000x00,
              0xFF0xFF};
   HANDLE hComm;
   DWORD DW_write;
   DWORD DW_read;
   DCB sPS;      // 씨리얼 포트 상태 저장
   COMMTIMEOUTS cTime;
   volatile unsigned int dly = 0;
   volatile unsigned int cnt = 0;
   volatile unsigned int icnt = 0;
 
   // CreateFile = File open 함수와 같다. COM1은 컴포트1이 열린다.
   hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    
   if(INVALID_HANDLE_VALUE == hComm)
   {
    printf("Com port open Error !\n");
    return 0;
   }
 
    
    // 버퍼 설정
   if== SetupComm(hComm, 40964096))
   {
    printf("Buffer setting Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
    /* 
     * 포트 초기화
     * DCB 구조체 사용
     * 길이
     * 속도
     */
   if== PurgeComm(hComm, PURGE_TXABORT | PURGE_TXCLEAR))
   {
    printf("Buffer initialization Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
   sPS.DCBlength = sizeof(sPS);
 
   if== GetCommState(hComm, &sPS))
   {
    printf("Port status read Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
   sPS.BaudRate = CBR_38400;  // 비트,초
   sPS.ByteSize = 8;        // 데이터 비트 전송
   sPS.Parity   = EVENPARITY;  // 짝수
   sPS.StopBits = ONESTOPBIT;  // 정지 비트
    
 
    // 위 세팅값을 핸들에 넣어준다.
   if== SetCommState(hComm, &sPS))
   {
    printf("Port status write Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
 
  *((unsigned short *)(msg + 11)) = Emb_Crc(msg);
 
  WriteFile(hComm, msg, sizeof(msg), &DW_write, 0);
  ReadFile(hComm, msg, 6&DW_read, 0);
 
 
  for(icnt = 0; icnt < msg[0]; icnt++)
  {
    printf("%02X ", msg[icnt]);
  }
  putchar('\n');
    
 
  printf("Com port open Success !\n");
  CloseHandle(hComm);      // 터미널은 닫아주어야한다.
 
  return 0;
}
 
 
unsigned short Emb_Crc(void *arg)
{
    unsigned short i;
    unsigned short j;
    unsigned short cnt;
    unsigned short crc=0xFFFF;
    unsigned short temp;
    unsigned char *buf = arg;
 
    cnt = (*buf) - 2;
 
    for(i=; i < cnt ; ++i)
    {
      crc^= *(buf + i);
      for(j=; j < ++j) 
      {
        if(!= (crc&0x0001))
        {
          crc=(crc>>1)^0x8408;
        }
        else
        {
          crc=(crc>>1);
        }
      }
      
    }
 
    return crc;
}
 
void text_out(unsigned char *msg)
{
  int icnt;
 
  for(icnt = 1;icnt <= 13 ;icnt++)
  {
    printf("%02d ", icnt);
    if(icnt == 13)
    {
      putchar('\n');
      for(icnt = 0;icnt < 13;icnt++)
      {
        printf("%02X "*(msg+icnt));
      }
      putchar('\n');
      break;
    }
  }
 
  return ;
}
cs


추가코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
DWORD DW_read;
 
 
 
  ReadFile(hComm, msg, 6&DW_read, 0);
 
 
  for(icnt = 0; icnt < msg[0]; icnt++)
  {
    printf("%02X ", msg[icnt]);
  }
 
 
 
ㆍ기존 소스에서 위 코드가 추가 되었다.
cs



ReadFile 함수를 통해 스펙내용과 동일한 값을 출력 할 수 있다.


실행 결과



Get Software Version




코드

unsigned char msg[128] = { 0x05,
                           0x00,
                           0x65,
                           0xFF, 0xFF};


CRC 비트 위치에 Crc 함수 반환값을 넣어준다.


코드

*((unsigned short *)(msg + msg[0] - 2)) = Emb_Crc(msg);


0

1

2

3

4

0x05

 

 

CRC

CRC


읽어오는 양은 13이므로 버퍼크기를 늘여준다.




스펙에 나와있는 비트 값들을 출력해 보자.


출력 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
#include <windows.h>
#include <stdio.h>
 
 
#define    I_Code_1       1
#define    Tag_it_HF      2
#define    ISO_15693      8
#define    I_Code_EPC     64
#define    I_Code_UID     128
 
 
 
void text_out(unsigned char *);
unsigned short Emb_Crc(void *);
 
 
 
int main()
{
  unsigned char msg[128= { 0x05,
                             0x00,
                             0x65,
                             0xFF0xFF};
   HANDLE hComm;
   DWORD DW_write;
   DWORD DW_read;
   DCB sPS;      // 씨리얼 포트 상태 저장
   COMMTIMEOUTS cTime;
   volatile unsigned int dly = 0;
   volatile unsigned int cnt = 0;
   volatile unsigned int icnt = 0;
 
   // CreateFile = File open 함수와 같다. COM1은 컴포트1이 열린다.
   hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    
   if(INVALID_HANDLE_VALUE == hComm)
   {
    printf("Com port open Error !\n");
    return 0;
   }
 
    
    // 버퍼 설정
   if== SetupComm(hComm, 40964096))
   {
    printf("Buffer setting Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
    /* 
     * 포트 초기화
     * DCB 구조체 사용
     * 길이
     * 속도
     */
   if== PurgeComm(hComm, PURGE_TXABORT | PURGE_TXCLEAR))
   {
    printf("Buffer initialization Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
   sPS.DCBlength = sizeof(sPS);
 
   if== GetCommState(hComm, &sPS))
   {
    printf("Port status read Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
   sPS.BaudRate = CBR_38400;  // 비트,초
   sPS.ByteSize = 8;        // 데이터 비트 전송
   sPS.Parity   = EVENPARITY;  // 짝수
   sPS.StopBits = ONESTOPBIT;  // 정지 비트
    
 
    // 위 세팅값을 핸들에 넣어준다.
   if== SetCommState(hComm, &sPS))
   {
    printf("Port status write Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
 
  *((unsigned short *)(msg + msg[0- 2)) = Emb_Crc(msg);
 
 
  WriteFile(hComm, msg, msg[0], &DW_write, 0);
  ReadFile(hComm, msg, 1&DW_read, 0);
  ReadFile(hComm, msg + 1, msg[0- 1&DW_read, 0);
 
 
  if(msg[3!= 0)
  {
    printf("error\n");
    CloseHandle(hComm);
    return 0;
  }
  printf("Revision status of the firmware : %02X%02X\n", msg[4], msg[5]);
  printf("Revision status of the development firmware : %02X\n", msg[6]);
  printf("HW-Type : %02X\n", msg[7]);
  printf("SW-TYPE : %02X\n", msg[8]);
  printf("suppor Transponders : \n");
  printf("\t\tI-Code UID : %s\n", (msg[10& I_Code_UID) ? "yes" : " no");
  printf("\t\tI-Code EPC : %s\n", (msg[10& I_Code_EPC) ? "yes" : " no");
  printf("\t\tISO 15693  : %s\n", (msg[10& ISO_15693) ? "yes" : " no");
  printf("\t\tTag-it HF  : %s\n", (msg[10& Tag_it_HF) ? "yes" : " no");
  printf("\t\tI-Code 1   : %s\n", (msg[10& I_Code_1) ? "yes" : " no");
 
 
 
  printf("Com port open Success !\n");
  CloseHandle(hComm);      // 터미널은 닫아주어야한다.
 
  return 0;
}
 
 
unsigned short Emb_Crc(void *arg)
{
    unsigned short i;
    unsigned short j;
    unsigned short cnt;
    unsigned short crc=0xFFFF;
    unsigned short temp;
    unsigned char *buf = arg;
 
    cnt = (*buf) - 2;
 
    for(i=; i < cnt ; ++i)
    {
      crc^= *(buf + i);
      for(j=; j < ++j) 
      {
        if(!= (crc&0x0001))
        {
          crc=(crc>>1)^0x8408;
        }
        else
        {
          crc=(crc>>1);
        }
      }
      
    }
 
    return crc;
}
 
void text_out(unsigned char *msg)
{
  int icnt;
 
  for(icnt = 1;icnt <= 13 ;icnt++)
  {
    printf("%02d ", icnt);
    if(icnt == 13)
    {
      putchar('\n');
      for(icnt = 0;icnt < 13;icnt++)
      {
        printf("%02X "*(msg+icnt));
      }
      putchar('\n');
      break;
    }
  }
 
  return ;
}
cs


실행 결과



Protocols for ISO15693 Host Commands




[0x22] Lick Multiple Blocks를 사용하면 카드를 사용할 수 없게 됨으로 사용해선 안된다.

[0xB0] Host commands 를 사용해 보자.



1번 bit에는 REQUST-DATA는 2bit 에 CRCrk 2bit가 존재함으로 7이다.



standard : 17

EPC : 16 / 20

UID : 27



[0x0B] Host command

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <windows.h>
#include <stdio.h>
 
 
unsigned short Emb_Crc(void *);
 
 
int main()
{
  unsigned char msg[128= { 0x07,
                             0x00,
                             0xB0,
                             0x01,
                             0x00,};
   HANDLE hComm;
   DWORD DW_write;
   DWORD DW_read;
   DCB sPS;      // 씨리얼 포트 상태 저장
   COMMTIMEOUTS cTime;
  
  
 
   // CreateFile = File open 함수와 같다. COM1은 컴포트1이 열린다.
   hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    
   if(INVALID_HANDLE_VALUE == hComm)
   {
    printf("Com port open Error !\n");
    return 0;
   }
 
    
    // 버퍼 설정
   if== SetupComm(hComm, 40964096))
   {
    printf("Buffer setting Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
    /* 
     * 포트 초기화
     * DCB 구조체 사용
     * 길이
     * 속도
     */
   if== PurgeComm(hComm, PURGE_TXABORT | PURGE_TXCLEAR))
   {
    printf("Buffer initialization Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
   sPS.DCBlength = sizeof(sPS);
 
   if== GetCommState(hComm, &sPS))
   {
    printf("Port status read Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
   sPS.BaudRate = CBR_38400;  // 비트,초
   sPS.ByteSize = 8;        // 데이터 비트 전송
   sPS.Parity   = EVENPARITY;  // 짝수
   sPS.StopBits = ONESTOPBIT;  // 정지 비트
    
 
    // 위 세팅값을 핸들에 넣어준다.
   if== SetCommState(hComm, &sPS))
   {
    printf("Port status write Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
 
  *((unsigned short *)(msg + msg[0- 2)) = Emb_Crc(msg);
 
 
  WriteFile(hComm, msg, msg[0], &DW_write, 0);
  ReadFile(hComm, msg, 1&DW_read, 0);
  ReadFile(hComm, msg + 1, msg[0- 1&DW_read, 0);
 
  printf("%d\n", msg[0]);
  printf("%02X\n",msg[3]);
  
  
  
  printf("Com port open Success !\n");
  CloseHandle(hComm);      // 터미널은 닫아주어야한다.
 
  return 0;
}
 
 
unsigned short Emb_Crc(void *arg)
{
    unsigned short i;
    unsigned short j;
    unsigned short cnt;
    unsigned short crc=0xFFFF;
    unsigned short temp;
    unsigned char *buf = arg;
 
    cnt = (*buf) - 2;
 
    for(i=; i < cnt ; ++i)
    {
      crc^= *(buf + i);
      for(j=; j < ++j) 
      {
        if(!= (crc&0x0001))
        {
          crc=(crc>>1)^0x8408;
        }
        else
        {
          crc=(crc>>1);
        }
      }
      
    }
 
    return crc;
}
cs


카드가 있을 때 RESPONSE-DATA


카드가 없을 때 RESPONSE-DATA


[카드가 있을 때 Status 값]



[카드가 없을 때 Status 값]



카드의 종류를 식별하고 카드가 있는지를 검사하는 프로그램 코드는 아래와 같다.


Tag Data

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <windows.h>
#include <stdio.h>
 
 
unsigned short Emb_Crc(void *);
 
 
int main()
{
  unsigned char msg[128= { 0x07,
                 0x00,
                 0xB0,
                 0x01,
                 0x00,};
   HANDLE hComm;
   DWORD DW_write;
   DWORD DW_read;
   DCB sPS;      // 씨리얼 포트 상태 저장
   COMMTIMEOUTS cTime;
  
  
 
   // CreateFile = File open 함수와 같다. COM1은 컴포트1이 열린다.
   hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    
   if(INVALID_HANDLE_VALUE == hComm)
   {
    printf("Com port open Error !\n");
    return 0;
   }
 
    
    // 버퍼 설정
   if== SetupComm(hComm, 40964096))
   {
    printf("Buffer setting Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
    /* 
     * 포트 초기화
     * DCB 구조체 사용
     * 길이
     * 속도
     */
   if== PurgeComm(hComm, PURGE_TXABORT | PURGE_TXCLEAR))
   {
    printf("Buffer initialization Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
   sPS.DCBlength = sizeof(sPS);
 
   if== GetCommState(hComm, &sPS))
   {
    printf("Port status read Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
   sPS.BaudRate = CBR_38400;  // 비트,초
   sPS.ByteSize = 8;        // 데이터 비트 전송
   sPS.Parity   = EVENPARITY;  // 짝수
   sPS.StopBits = ONESTOPBIT;  // 정지 비트
    
 
    // 위 세팅값을 핸들에 넣어준다.
   if== SetCommState(hComm, &sPS))
   {
    printf("Port status write Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
 
  *((unsigned short *)(msg + msg[0- 2)) = Emb_Crc(msg);
 
 
  WriteFile(hComm, msg, msg[0], &DW_write, 0);
  ReadFile(hComm, msg, 1&DW_read, 0);
  ReadFile(hComm, msg + 1, msg[0- 1&DW_read, 0);
 
  switch(msg[0])
  {
    case 17 :
      printf("RESPONSE-DATA : standard\n");
      break;
 
    case 16 :
      printf("RESPONSE-DATA : I-Code EPC\n");
      break;
 
    case 20 :
      printf("RESPONSE-DATA : I-Code EPC\n");
      break;
 
    case 27 :
      printf("RESPONSE-DATA : I-Code UID\n");
      break;
 
    default :
      printf("No such card ! \n");
      break;
 
  }
  
  
  
  
  printf("Com port open Success !\n");
  CloseHandle(hComm);      // 터미널은 닫아주어야한다.
 
  return 0;
}
 
 
unsigned short Emb_Crc(void *arg)
{
    unsigned short i;
    unsigned short j;
    unsigned short cnt;
    unsigned short crc=0xFFFF;
    unsigned short temp;
    unsigned char *buf = arg;
 
    cnt = (*buf) - 2;
 
    for(i=; i < cnt ; ++i)
    {
      crc^= *(buf + i);
      for(j=; j < ++j) 
      {
        if(!= (crc&0x0001))
        {
          crc=(crc>>1)^0x8408;
        }
        else
        {
          crc=(crc>>1);
        }
      }
      
    }
 
    return crc;
}
cs


실행 결과


standard를 분석해보자.



RF-TYPE

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#include <windows.h>
#include <stdio.h>
 
 
unsigned short Emb_Crc(void *);
 
 
int main()
{
  unsigned char msg[128= { 0x07,
                 0x00,
                 0xB0,
                 0x01,
                 0x00,};
   HANDLE hComm;
   DWORD DW_write;
   DWORD DW_read;
   DCB sPS;      // 씨리얼 포트 상태 저장
   COMMTIMEOUTS cTime;
  
  
 
   // CreateFile = File open 함수와 같다. COM1은 컴포트1이 열린다.
   hComm = CreateFile("COM1", GENERIC_READ | GENERIC_WRITE, 0, NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    
   if(INVALID_HANDLE_VALUE == hComm)
   {
    printf("Com port open Error !\n");
    return 0;
   }
 
    
    // 버퍼 설정
   if== SetupComm(hComm, 40964096))
   {
    printf("Buffer setting Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
    /* 
     * 포트 초기화
     * DCB 구조체 사용
     * 길이
     * 속도
     */
   if== PurgeComm(hComm, PURGE_TXABORT | PURGE_TXCLEAR))
   {
    printf("Buffer initialization Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
   sPS.DCBlength = sizeof(sPS);
 
   if== GetCommState(hComm, &sPS))
   {
    printf("Port status read Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
   sPS.BaudRate = CBR_38400;  // 비트,초
   sPS.ByteSize = 8;        // 데이터 비트 전송
   sPS.Parity   = EVENPARITY;  // 짝수
   sPS.StopBits = ONESTOPBIT;  // 정지 비트
    
 
    // 위 세팅값을 핸들에 넣어준다.
   if== SetCommState(hComm, &sPS))
   {
    printf("Port status write Error !\n");
    CloseHandle(hComm);  
    return 0;
   }
 
 
  *((unsigned short *)(msg + msg[0- 2)) = Emb_Crc(msg);
 
 
  WriteFile(hComm, msg, msg[0], &DW_write, 0);
  ReadFile(hComm, msg, 1&DW_read, 0);
  ReadFile(hComm, msg + 1, msg[0- 1&DW_read, 0);
  printf("tag data : ");
  switch(msg[0])
  {
    case 17 :
      printf("[standard]\n");
      break;
 
    case 16 :
      printf("[I-Code EPC]\n");
      break;
 
    case 20 :
      printf("[ I-Code EPC]\n");
      break;
 
    case 27 :
      printf("[I-Code UID]\n");
      break;
 
    default :
      printf("[No such card ! ]\n");
      break;
 
  }
  
  printf("RF  TYPE : [%s]\n", (msg[5& 0xC0) ? "UHF Transponder" : 
       "13.56 MHz Transponder");
  
  
  printf("Com port open Success !\n");
  CloseHandle(hComm);      // 터미널은 닫아주어야한다.
 
  return 0;
}
 
 
unsigned short Emb_Crc(void *arg)
{
    unsigned short i;
    unsigned short j;
    unsigned short cnt;
    unsigned short crc=0xFFFF;
    unsigned short temp;
    unsigned char *buf = arg;
 
    cnt = (*buf) - 2;
 
    for(i=; i < cnt ; ++i)
    {
      crc^= *(buf + i);
      for(j=; j < ++j) 
      {
        if(!= (crc&0x0001))
        {
          crc=(crc>>1)^0x8408;
        }
        else
        {
          crc=(crc>>1);
        }
      }
      
    }
 
    return crc;
}
cs


실행 결과



728x90
반응형