Firmware SDK
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
bc_tag_nfc.c
1 #include <bc_tag_nfc.h>
2 #include <bc_timer.h>
3 
4 #define _BC_TAG_NFC_TNF_WELL_KNOWN 0x01
5 
6 #define _BC_TAG_NFC_BLOCK_SIZE 16
7 
8 static bool _bc_tag_nfc_ndef_add_record_head(bc_tag_nfc_ndef_t *self, size_t payload_length);
9 
10 bool bc_tag_nfc_init(bc_tag_nfc_t *self, bc_i2c_channel_t i2c_channel, uint8_t i2c_address)
11 {
12  memset(self, 0, sizeof(*self));
13 
14  self->_i2c_channel = i2c_channel;
15 
16  self->_i2c_address = i2c_address;
17 
18  bc_timer_init();
19 
20  bc_i2c_init(self->_i2c_channel, BC_I2C_SPEED_400_KHZ);
21 
22  bc_i2c_memory_transfer_t transfer;
23 
24  uint8_t config[_BC_TAG_NFC_BLOCK_SIZE];
25 
26  transfer.device_address = self->_i2c_address;
27 
28  transfer.memory_address = 0x00;
29 
30  transfer.buffer = config;
31 
32  transfer.length = sizeof(config);
33 
34  if (!bc_i2c_memory_read(self->_i2c_channel, &transfer))
35  {
36  return false;
37  }
38 
39  if ((config[12] | config[13] | config[14] | config[15]) == 0x00 ) //check lock tag
40  {
41  config[0] = self->_i2c_address << 1;
42 
43  config[12] = 0xE1;
44 
45  config[13] = 0x10;
46 
47  config[14] = 0x6D;
48 
49  config[15] = 0x00;
50 
51  if (!bc_i2c_memory_write(self->_i2c_channel, &transfer))
52  {
53  return false;
54  }
55 
57 
58  bc_timer_delay(5000);
59 
60  bc_timer_stop();
61  }
62 
63  return true;
64 }
65 
66 bool bc_tag_nfc_memory_read(bc_tag_nfc_t *self, void *buffer, size_t length)
67 {
68  if ((length % _BC_TAG_NFC_BLOCK_SIZE != 0) || (length > BC_TAG_NFC_BUFFER_SIZE))
69  {
70  return false;
71  }
72 
73  size_t read_length = 0;
74 
75  uint8_t address = 0x01;
76 
77  bc_i2c_memory_transfer_t transfer;
78 
79  transfer.device_address = self->_i2c_address;
80 
81  transfer.length = _BC_TAG_NFC_BLOCK_SIZE;
82 
83  while ((read_length < length) && (address < 0x37))
84  {
85  transfer.memory_address = address;
86 
87  transfer.buffer = (uint8_t *) buffer + read_length;
88 
89  if (!bc_i2c_memory_read(self->_i2c_channel, &transfer))
90  {
91  return false;
92  }
93 
94  address++;
95 
96  read_length += _BC_TAG_NFC_BLOCK_SIZE;
97  }
98 
99  return true;
100 }
101 
102 bool bc_tag_nfc_memory_write(bc_tag_nfc_t *self, void *buffer, size_t length)
103 {
104  if ((length % _BC_TAG_NFC_BLOCK_SIZE != 0) || (length > BC_TAG_NFC_BUFFER_SIZE))
105  {
106  return false;
107  }
108 
109  size_t write_length = 0;
110 
111  uint8_t address = 0x01;
112 
113  bc_i2c_memory_transfer_t transfer;
114 
115  transfer.device_address = self->_i2c_address;
116 
117  transfer.length = _BC_TAG_NFC_BLOCK_SIZE;
118 
119  while ((write_length < length) && (address < 0x37))
120  {
121  transfer.memory_address = address;
122 
123  transfer.buffer = (uint8_t *) buffer + write_length;
124 
125  if (!bc_i2c_memory_write(self->_i2c_channel, &transfer))
126  {
127  return false;
128  }
129 
130  bc_timer_start();
131 
132  bc_timer_delay(5000);
133 
134  bc_timer_stop();
135 
136  address++;
137 
138  write_length += _BC_TAG_NFC_BLOCK_SIZE;
139  }
140 
141  return true;
142 }
143 
145 {
146  size_t length = ndef->_length;
147 
148  if (((length % _BC_TAG_NFC_BLOCK_SIZE) != 0))
149  {
150  length = ((length / _BC_TAG_NFC_BLOCK_SIZE) + 1) * _BC_TAG_NFC_BLOCK_SIZE;
151  }
152 
153  return bc_tag_nfc_memory_write(self, ndef->_buffer, length);
154 }
155 
157 {
158  self->_buffer[0] = 0x03;
159 
160  self->_buffer[1] = 0x00;
161 
162  self->_buffer[2] = 0xFE;
163 
164  self->_length = 3;
165 
166  self->_encoded_size = 0;
167 
168  self->_last_tnf_pos = 0;
169 }
170 
171 bool bc_tag_nfc_ndef_add_text(bc_tag_nfc_ndef_t *self, const char *text, const char *encoding)
172 {
173  size_t text_length = strlen(text);
174 
175  size_t encoding_length = strlen(encoding);
176 
177  if (!_bc_tag_nfc_ndef_add_record_head(self, encoding_length + 1 + text_length))
178  {
179  return false;
180  }
181 
182  self->_buffer[self->_length++] = 0x54; // type RTD_TEXT
183 
184  self->_buffer[self->_length++] = encoding_length;
185 
186  memcpy(self->_buffer + self->_length, encoding, encoding_length);
187 
188  self->_length += encoding_length;
189 
190  memcpy(self->_buffer + self->_length, text, text_length);
191 
192  self->_length += text_length;
193 
194  self->_buffer[self->_length++] = 0xFE; // terminator
195 
196  return true;
197 }
198 
199 bool bc_tag_nfc_ndef_add_uri(bc_tag_nfc_ndef_t *self, const char *uri)
200 {
201  size_t uri_length = strlen(uri);
202 
203  if (!_bc_tag_nfc_ndef_add_record_head(self, 1 + uri_length))
204  {
205  return false;
206  }
207  self->_buffer[self->_length++] = 0x55; // type RTD_TEXT
208 
209  self->_buffer[self->_length++] = 0;
210 
211  memcpy(self->_buffer + self->_length, uri, uri_length);
212 
213  self->_length += uri_length;
214 
215  self->_buffer[self->_length++] = 0xFE; // terminator
216 
217  return true;
218 }
219 
220 static bool _bc_tag_nfc_ndef_add_record_head(bc_tag_nfc_ndef_t *self, size_t payload_length)
221 {
222  size_t head_length = 2 + (payload_length > 0xff ? 4 : 1) + 1; // tnf + type_length + type
223 
224  if ((head_length + payload_length > BC_TAG_NFC_BUFFER_SIZE))
225  {
226  return false;
227  }
228 
229  if (self->_last_tnf_pos != 0)
230  {
231  self->_buffer[self->_last_tnf_pos] &= ~0x40; // remove flag last record
232  }
233 
234  if (self->_encoded_size == 0)
235  {
236  self->_buffer[1] = 0xff;
237 
238  self->_length = 4;
239  }
240  else
241  {
242  self->_length--;
243  }
244 
245  self->_encoded_size += head_length + payload_length;
246 
247  self->_buffer[2] = self->_encoded_size >> 8;
248 
249  self->_buffer[3] = self->_encoded_size;
250 
251  self->_buffer[self->_length] = _BC_TAG_NFC_TNF_WELL_KNOWN | 0x40;
252 
253  if (self->_length == 4)
254  {
255  self->_buffer[self->_length] |= 0x80;
256  }
257 
258  if (payload_length <= 0xff)
259  {
260  self->_buffer[self->_length] |= 0x10;
261  }
262 
263  self->_last_tnf_pos = self->_length;
264 
265  self->_length++;
266 
267  self->_buffer[self->_length++] = 1; // type length
268 
269  if (payload_length <= 0xFF) // short record
270  {
271  self->_buffer[self->_length++] = payload_length;
272  }
273  else // long format
274  {
275  self->_buffer[self->_length++] = payload_length >> 24;
276 
277  self->_buffer[self->_length++] = payload_length >> 16;
278 
279  self->_buffer[self->_length++] = payload_length >> 8;
280 
281  self->_buffer[self->_length++] = payload_length & 0xff;
282  }
283 
284  return true;
285 }
void * buffer
Pointer to buffer which is being written or read.
Definition: bc_i2c.h:66
bool bc_tag_nfc_memory_read(bc_tag_nfc_t *self, void *buffer, size_t length)
Read from memory.
Definition: bc_tag_nfc.c:66
I2C communication speed is 400 kHz.
Definition: bc_i2c.h:36
bool bc_tag_nfc_ndef_add_uri(bc_tag_nfc_ndef_t *self, const char *uri)
Add ndef uri record.
Definition: bc_tag_nfc.c:199
void bc_timer_start(void)
Start timer.
Definition: bc_timer.c:24
bool bc_i2c_memory_read(bc_i2c_channel_t channel, const bc_i2c_memory_transfer_t *transfer)
Memory read from I2C channel.
Definition: bc_i2c.c:365
bool bc_tag_nfc_memory_write_ndef(bc_tag_nfc_t *self, bc_tag_nfc_ndef_t *ndef)
Write to memory.
Definition: bc_tag_nfc.c:144
void bc_timer_delay(uint16_t microseconds)
Relative delay.
Definition: bc_timer.c:40
void bc_i2c_init(bc_i2c_channel_t channel, bc_i2c_speed_t speed)
Initialize I2C channel.
Definition: bc_i2c.c:54
void bc_timer_stop(void)
Stop timer.
Definition: bc_timer.c:55
uint32_t memory_address
8-bit I2C memory address (it can be extended to 16-bit format if OR-ed with BC_I2C_MEMORY_ADDRESS_16_...
Definition: bc_i2c.h:63
uint8_t device_address
7-bit I2C device address
Definition: bc_i2c.h:60
I2C memory transfer parameters.
Definition: bc_i2c.h:57
Instance.
Definition: bc_tag_nfc.h:18
bc_i2c_channel_t
I2C channels.
Definition: bc_i2c.h:15
bool bc_tag_nfc_memory_write(bc_tag_nfc_t *self, void *buffer, size_t length)
Write to memory.
Definition: bc_tag_nfc.c:102
bool bc_tag_nfc_init(bc_tag_nfc_t *self, bc_i2c_channel_t i2c_channel, uint8_t i2c_address)
Initialize NFC Tag.
Definition: bc_tag_nfc.c:10
bool bc_tag_nfc_ndef_add_text(bc_tag_nfc_ndef_t *self, const char *text, const char *encoding)
Add ndef text record.
Definition: bc_tag_nfc.c:171
size_t length
Length of buffer which is being written or read.
Definition: bc_i2c.h:69
bool bc_i2c_memory_write(bc_i2c_channel_t channel, const bc_i2c_memory_transfer_t *transfer)
Memory write to I2C channel.
Definition: bc_i2c.c:327
void bc_timer_init(void)
Initialize timer.
Definition: bc_timer.c:18
NDEF Instance.
Definition: bc_tag_nfc.h:27
void bc_tag_nfc_ndef_init(bc_tag_nfc_ndef_t *self)
Initialize NDEF.
Definition: bc_tag_nfc.c:156