See changelog v0.9.8
[hackover2013-badge-firmware.git] / drivers / sensors / pn532 / pn532_bus_i2c.c
1 /**************************************************************************/
2 /*!
3 @file pn532_bus_i2c.c
4 @author K. Townsend (microBuilder.eu)
5
6 @section LICENSE
7
8 Software License Agreement (BSD License)
9
10 Copyright (c) 2012, microBuilder SARL
11 All rights reserved.
12
13 Redistribution and use in source and binary forms, with or without
14 modification, are permitted provided that the following conditions are met:
15 1. Redistributions of source code must retain the above copyright
16 notice, this list of conditions and the following disclaimer.
17 2. Redistributions in binary form must reproduce the above copyright
18 notice, this list of conditions and the following disclaimer in the
19 documentation and/or other materials provided with the distribution.
20 3. Neither the name of the copyright holders nor the
21 names of its contributors may be used to endorse or promote products
22 derived from this software without specific prior written permission.
23
24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
25 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
28 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35 /**************************************************************************/
36 #include <string.h>
37
38 #include "pn532.h"
39 #include "pn532_bus.h"
40
41 #ifdef PN532_BUS_I2C
42
43 #include "core/systick/systick.h"
44 #include "core/gpio/gpio.h"
45 #include "core/i2c/i2c.h"
46
47 extern volatile uint8_t I2CMasterBuffer[I2C_BUFSIZE];
48 extern volatile uint8_t I2CSlaveBuffer[I2C_BUFSIZE];
49 extern volatile uint32_t I2CReadLength, I2CWriteLength;
50
51 /* ======================================================================
52 PRIVATE FUNCTIONS
53 ====================================================================== */
54
55 /**************************************************************************/
56 /*!
57 @brief Writes an 8 bit value over I2C
58
59 @note Possible error messages are:
60
61 - PN532_ERROR_I2C_NACK
62 */
63 /**************************************************************************/
64 pn532_error_t pn532_bus_i2c_WriteData (const byte_t * pbtData, const size_t szData)
65 {
66 uint32_t i2cState;
67
68 // Clear write buffers
69 uint32_t i;
70 for ( i = 0; i < I2C_BUFSIZE; i++ )
71 {
72 I2CMasterBuffer[i] = 0x00;
73 }
74
75 // Send the specified bytes
76 I2CWriteLength = szData+1;
77 I2CReadLength = 0;
78 I2CMasterBuffer[0] = PN532_I2C_ADDRESS; // I2C device address
79 for ( i = 0; i < szData; i++ )
80 {
81 I2CMasterBuffer[i+1] = pbtData[i];
82 }
83 i2cState = i2cEngine();
84
85 // Check if we got an ACK
86 if ((i2cState == I2CSTATE_NACK) || (i2cState == I2CSTATE_SLA_NACK))
87 {
88 // I2C slave didn't acknowledge the master transfer
89 // The PN532 probably isn't connected properly or the
90 // bus select pins are in the wrong state
91 return PN532_ERROR_I2C_NACK;
92 }
93
94 return PN532_ERROR_NONE;
95 }
96
97 /**************************************************************************/
98 /*!
99 @brief Checks the 'IRQ' pin to know if the PN532 is ready to send
100 a response or not
101
102 @note The IRQ bit may stay high intentionally, and this isn't
103 always an error condition. When PN532_COMMAND_INLISTPASSIVETARGET
104 is sent, for example, the PN532 will wait until a card
105 enters the magnetic field, and IRQ will remain high since
106 there is no response ready yet. The IRQ pin will go low
107 as soon as a card enters the magentic field and the data
108 has been retrieved from it.
109
110 @returns 1 if a response is ready, 0 if the PN532 is still busy or a
111 timeout occurred
112 */
113 /**************************************************************************/
114 uint8_t pn532_bus_i2c_WaitForReady(void)
115 {
116 uint8_t busy = 1;
117 // uint8_t busyTimeout = 0;
118
119 while (busy)
120 {
121 // For now, we wait forever until a command is ready
122 // ToDo: Add user-specified timeout
123 busy = gpioGetValue(PN532_I2C_IRQPORT, PN532_I2C_IRQPIN);
124 systickDelay(1);
125 // busyTimeout++;
126 // if (busyTimeout == PN532_I2C_READYTIMEOUT)
127 // {
128 // return false;
129 // }
130 }
131
132 return true;
133 }
134
135 /**************************************************************************/
136 /*!
137 @brief Builds a standard PN532 frame using the supplied data
138
139 @param pbtFrame Pointer to the field that will hold the frame data
140 @param pszFrame Pointer to the field that will hold the frame length
141 @param pbtData Pointer to the data to insert in a frame
142 @param swData Length of the data to insert in bytes
143
144 @note Possible error messages are:
145
146 - PN532_ERROR_EXTENDEDFRAME
147 */
148 /**************************************************************************/
149 pn532_error_t pn532_bus_i2c_BuildFrame(byte_t * pbtFrame, size_t * pszFrame, const byte_t * pbtData, const size_t szData)
150 {
151 if (szData > PN532_NORMAL_FRAME__DATA_MAX_LEN)
152 {
153 // Extended frames currently unsupported
154 return PN532_ERROR_EXTENDEDFRAME;
155 }
156
157 // LEN - Packet length = data length (len) + checksum (1) + end of stream marker (1)
158 pbtFrame[3] = szData + 1;
159 // LCS - Packet length checksum
160 pbtFrame[4] = 256 - (szData + 1);
161 // TFI
162 pbtFrame[5] = 0xD4;
163 // DATA - Copy the PN53X command into the packet buffer
164 memcpy (pbtFrame + 6, pbtData, szData);
165
166 // DCS - Calculate data payload checksum
167 byte_t btDCS = (256 - 0xD4);
168 size_t szPos;
169 for (szPos = 0; szPos < szData; szPos++)
170 {
171 btDCS -= pbtData[szPos];
172 }
173 pbtFrame[6 + szData] = btDCS;
174
175 // 0x00 - End of stream marker
176 pbtFrame[szData + 7] = 0x00;
177
178 (*pszFrame) = szData + PN532_NORMAL_FRAME__OVERHEAD;
179
180 return PN532_ERROR_NONE;
181 }
182
183 /* ======================================================================
184 PUBLIC FUNCTIONS
185 ====================================================================== */
186
187 /**************************************************************************/
188 /*!
189 @brief Initialises I2C and configures the PN532 HW
190 */
191 /**************************************************************************/
192 void pn532_bus_HWInit(void)
193 {
194 #ifdef PN532_DEBUGMODE
195 PN532_DEBUG("Initialising I2C %s", CFG_PRINTF_NEWLINE);
196 #endif
197 i2cInit(I2CMASTER);
198
199 // Set IRQ pin to input
200 gpioSetDir(PN532_I2C_IRQPORT, PN532_I2C_IRQPIN, gpioDirection_Input);
201
202 // Set reset pin as output and reset device
203 gpioSetDir(PN532_RSTPD_PORT, PN532_RSTPD_PIN, gpioDirection_Output);
204 #ifdef PN532_DEBUGMODE
205 PN532_DEBUG("Resetting the PN532...\r\n");
206 #endif
207 gpioSetValue(PN532_RSTPD_PORT, PN532_RSTPD_PIN, 0);
208 systickDelay(400);
209 gpioSetValue(PN532_RSTPD_PORT, PN532_RSTPD_PIN, 1);
210
211 // Wait for the PN532 to finish booting
212 systickDelay(100);
213 }
214
215 /**************************************************************************/
216 /*!
217 @brief Sends the specified command to the PN532, automatically
218 creating an appropriate frame for it
219
220 @param pdbData Pointer to the byte data to send
221 @param szData Length in bytes of the data to send
222
223 @note Possible error messages are:
224
225 - PN532_ERROR_EXTENDEDFRAME // Extended frames not supported
226 - PN532_ERROR_BUSY // Already busy with a command
227 - PN532_ERROR_I2C_NACK // No ACK on I2C
228 - PN532_ERROR_READYSTATUSTIMEOUT // Timeout waiting for ready bit
229 - PN532_ERROR_INVALIDACK // No ACK frame received
230 */
231 /**************************************************************************/
232 pn532_error_t pn532_bus_SendCommand(const byte_t * pbtData, const size_t szData)
233 {
234 pn532_error_t error = PN532_ERROR_NONE;
235 pn532_pcb_t *pn532 = pn532GetPCB();
236
237 // Check if we're busy
238 if (pn532->state == PN532_STATE_BUSY)
239 {
240 return PN532_ERROR_BUSY;
241 }
242
243 // Flag the stack as busy
244 pn532->state = PN532_STATE_BUSY;
245
246 // --------------------------------------------------------------------
247 // Send the command frame
248 // --------------------------------------------------------------------
249 byte_t abtFrame[PN532_BUFFER_LEN] = { 0x00, 0x00, 0xff };
250 size_t szFrame = 0;
251
252 // Build the frame
253 pn532_bus_i2c_BuildFrame (abtFrame, &szFrame, pbtData, szData);
254
255 // Keep track of the last command that was sent
256 pn532->lastCommand = pbtData[0];
257
258 // Output the frame data for debugging if requested
259 #ifdef PN532_DEBUGMODE
260 PN532_DEBUG("Sending (%02d): ", szFrame);
261 pn532PrintHex(abtFrame, szFrame);
262 #endif
263
264 // Send data to the PN532
265 error = pn532_bus_i2c_WriteData(abtFrame, szFrame);
266
267 if (error == PN532_ERROR_I2C_NACK)
268 {
269 // Most likely error is PN532_ERROR_I2C_NACK
270 // meaning no I2C ACK received from the PN532
271 #ifdef PN532_DEBUGMODE
272 PN532_DEBUG ("No ACK received on I2C bus%s", CFG_PRINTF_NEWLINE);
273 #endif
274 pn532->state = PN532_STATE_READY;
275 return error;
276 }
277
278 // --------------------------------------------------------------------
279 // Wait for the IRQ/Ready flag
280 // --------------------------------------------------------------------
281 if (!(pn532_bus_i2c_WaitForReady()))
282 {
283 pn532->state = PN532_STATE_READY;
284 #ifdef PN532_DEBUGMODE
285 PN532_DEBUG ("Timed out waiting for IRQ/Ready%s", CFG_PRINTF_NEWLINE);
286 #endif
287 return PN532_ERROR_READYSTATUSTIMEOUT;
288 }
289
290 // --------------------------------------------------------------------
291 // Read the ACK frame
292 // --------------------------------------------------------------------
293 uint32_t i;
294 // Clear buffer
295 for ( i = 0; i < I2C_BUFSIZE; i++ )
296 {
297 I2CMasterBuffer[i] = 0x00;
298 }
299 I2CWriteLength = 0;
300 I2CReadLength = 7; // ACK + Ready bit = 7
301 I2CMasterBuffer[0] = PN532_I2C_ADDRESS | PN532_I2C_READBIT;
302 i2cEngine();
303
304 // Make sure the received ACK matches the prototype
305 const byte_t abtAck[6] = { 0x00, 0x00, 0xff, 0x00, 0xff, 0x00 };
306 byte_t abtRxBuf[6];
307 // memcpy(abtRxBuf, I2CSlaveBuffer+1, 6);
308 for ( i = 0; i < 6; i++ )
309 {
310 abtRxBuf[i] = I2CSlaveBuffer[i+1];
311 }
312 if (0 != (memcmp (abtRxBuf, abtAck, 6)))
313 {
314 #ifdef PN532_DEBUGMODE
315 PN532_DEBUG ("Invalid ACK: ");
316 pn532PrintHex(abtRxBuf, 6);
317 PN532_DEBUG("%s", CFG_PRINTF_NEWLINE);
318 #endif
319 pn532->state = PN532_STATE_READY;
320 return PN532_ERROR_INVALIDACK;
321 }
322
323 // --------------------------------------------------------------------
324 // Wait for the post-ACK IRQ/Ready flag
325 // --------------------------------------------------------------------
326 if (!(pn532_bus_i2c_WaitForReady()))
327 {
328 pn532->state = PN532_STATE_READY;
329 #ifdef PN532_DEBUGMODE
330 PN532_DEBUG ("Timed out waiting for IRQ/Ready%s", CFG_PRINTF_NEWLINE);
331 #endif
332 return PN532_ERROR_READYSTATUSTIMEOUT;
333 }
334
335 pn532->state = PN532_STATE_READY;
336 return PN532_ERROR_NONE;
337 }
338
339 /**************************************************************************/
340 /*!
341 @brief Reads a response from the PN532
342
343 @note Possible error message are:
344
345 - PN532_ERROR_BUSY
346 - PN532_ERROR_RESPONSEBUFFEREMPTY
347 - PN532_ERROR_PREAMBLEMISMATCH
348 - PN532_ERROR_APPLEVELERROR
349 - PN532_ERROR_EXTENDEDFRAME
350 - PN532_ERROR_LENCHECKSUMMISMATCH
351 */
352 /**************************************************************************/
353 pn532_error_t pn532_bus_ReadResponse(byte_t * pbtResponse, size_t * pszRxLen)
354 {
355 pn532_pcb_t *pn532 = pn532GetPCB();
356
357 // Check if we're busy
358 if (pn532->state == PN532_STATE_BUSY)
359 {
360 return PN532_ERROR_BUSY;
361 }
362
363 // Flag the stack as busy
364 pn532->state = PN532_STATE_BUSY;
365
366 // Reset the app error flag
367 pn532->appError = PN532_APPERROR_NONE;
368
369 uint32_t i;
370 for ( i = 0; i < I2C_BUFSIZE; i++ )
371 {
372 I2CMasterBuffer[i] = 0x00;
373 }
374 I2CWriteLength = 0;
375 I2CReadLength = I2C_BUFSIZE;
376 I2CMasterBuffer[0] = PN532_I2C_ADDRESS | PN532_I2C_READBIT;
377 i2cEngine();
378
379 // Display the raw response data for debugging if requested
380 #ifdef PN532_DEBUGMODE
381 PN532_DEBUG("Received (%02d): ", I2C_BUFSIZE-1);
382 pn532PrintHex(pbtResponse, I2C_BUFSIZE-1);
383 #endif
384
385 // Use the full I2C buffer size for now (until we're sure we have a good frame)
386 *pszRxLen = I2C_BUFSIZE - 1;
387
388 // Fill the response buffer from I2C (skipping the leading 'ready' bit when using I2C)
389 // memcpy(pbtResponse, I2CSlaveBuffer+1, I2C_BUFSIZE-1);
390 for ( i = 0; i < I2C_BUFSIZE-1; i++ )
391 {
392 pbtResponse[i] = I2CSlaveBuffer[i+1];
393 }
394
395 // Check the frame type
396 if ((0x01 == pbtResponse[3]) && (0xff == pbtResponse[4]))
397 {
398 // Error frame
399 #ifdef PN532_DEBUGMODE
400 PN532_DEBUG("Application level error (0x%02x)%s", pbtResponse[5], CFG_PRINTF_NEWLINE);
401 #endif
402 // Set application error message ID
403 pn532->appError = pbtResponse[5];
404 pn532->state = PN532_STATE_READY;
405 return PN532_ERROR_APPLEVELERROR;
406 }
407 else if ((0xff == pbtResponse[3]) && (0xff == pbtResponse[4]))
408 {
409 // Extended frame
410 #ifdef PN532_DEBUGMODE
411 PN532_DEBUG("Extended frames currently unsupported%s", CFG_PRINTF_NEWLINE);
412 #endif
413 pn532->state = PN532_STATE_READY;
414 return PN532_ERROR_EXTENDEDFRAME;
415 }
416 else
417 {
418 // Normal frame
419 if (256 != (pbtResponse[3] + pbtResponse[4]))
420 {
421 // TODO: Retry
422 #ifdef PN532_DEBUGMODE
423 PN532_DEBUG("Length checksum mismatch%s", CFG_PRINTF_NEWLINE);
424 #endif
425 pn532->state = PN532_STATE_READY;
426 return PN532_ERROR_LENCHECKSUMMISMATCH;
427 }
428 }
429
430 // Figure out how large the response really is
431 // Response Frame Len = pbtResponse[3] + 7 (00 00 FF LEN LCS TFI [DATA] DCS)
432 *pszRxLen = pbtResponse[3] + 7;
433
434 pn532->state = PN532_STATE_READY;
435 return PN532_ERROR_NONE;
436 }
437
438 /**************************************************************************/
439 /*!
440 @brief Sends the wakeup sequence to the PN532.
441
442 @note Possible error message are:
443
444 - PN532_ERROR_BUSY
445 - PN532_ERROR_I2C_NACK // No I2C ACK
446 - PN532_ERROR_READYSTATUSTIMEOUT // Timed out waiting for ready bit
447 */
448 /**************************************************************************/
449 pn532_error_t pn532_bus_Wakeup(void)
450 {
451 pn532_error_t error = PN532_ERROR_NONE;
452 byte_t abtWakeUp[] = { 0x55,0x55,0x00,0x00,0x00,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00,0x00,0xff,0x03,0xfd,0xd4,0x14,0x01,0x17,0x00 };
453 uint32_t i;
454
455 pn532_pcb_t *pn532 = pn532GetPCB();
456
457 #ifdef PN532_DEBUGMODE
458 PN532_DEBUG("Sending Wakeup Sequence%s", CFG_PRINTF_NEWLINE);
459 #endif
460 error = pn532_bus_i2c_WriteData(abtWakeUp,sizeof(abtWakeUp));
461 systickDelay(100);
462
463 // Wait for the IRQ/Ready flag to indicate a response is ready
464 if (!(pn532_bus_i2c_WaitForReady()))
465 {
466 error = PN532_ERROR_READYSTATUSTIMEOUT;
467 }
468
469 // Read and discard the ACK frame
470 for ( i = 0; i < I2C_BUFSIZE; i++ )
471 {
472 I2CMasterBuffer[i] = 0x00;
473 }
474 I2CWriteLength = 0;
475 I2CReadLength = 7; // ACK + Ready bit = 7
476 I2CMasterBuffer[0] = PN532_I2C_ADDRESS | PN532_I2C_READBIT;
477 i2cEngine();
478 systickDelay(1);
479
480 // Wait for the IRQ/Ready flag to indicate a response is ready
481 if (!(pn532_bus_i2c_WaitForReady()))
482 {
483 error = PN532_ERROR_READYSTATUSTIMEOUT;
484 }
485
486 pn532->state = PN532_STATE_READY;
487 return error;
488 }
489
490 #endif // #ifdef PN532_BUS_I2C
This page took 0.075379 seconds and 5 git commands to generate.