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