nfc test on MQX4.1
[nfc-test.git] / pn51x.c
blobd9ba68bd8731f164adbab8ab6df0996c6a5f3165
2 /* NXP pn51x NFC driver */
4 #include "common.h"
5 #include "pn51x.h"
6 #include "pcd_config.h"
8 #include "nfc_spi.h"
10 #ifdef HANDLE_INTR_IN_TASK
11 // pn51x extern interrupt task parameters
12 #define NFC_TASK_NUM_MESSAGES 16
13 #define NFC_TASK_TEMPLATE_INDEX 0
14 #define NFC_TASK_ADDRESS _nfc_intr_task
15 #define NFC_TASK_STACKSIZE 1600
16 #define NFC_TASK_NAME "NFC Task"
17 #define NFC_TASK_ATTRIBUTES 0
18 #define NFC_TASK_CREATION_PARAMETER 0
19 #define NFC_TASK_DEFAULT_TIME_SLICE 0
20 #define NFC_TASK_PRIORITY 8
21 #endif
23 #define PN51X_EXT_INTR_LEVEL 5
25 #define PN51X_FIFO_MAX_DEEPTH 64
26 #define PN51X_FIFO_MAX_FIFO_ALLOWED 62
27 #define PN51X_FIFO_WATER_LEVEL 58
29 #if 0
30 #define PN51X_RESET_PIN (GPIO_PORT_A | GPIO_PIN14)
31 #define PN51X_RESET_PIN_MUX_GPIO LWGPIO_MUX_A14_GPIO
32 #else
33 #define PN51X_RESET_PIN (GPIO_PORT_B | GPIO_PIN9)
34 #define PN51X_RESET_PIN_MUX_GPIO 1
35 #endif
37 /* otg transceiver external intrrupt ,falling mode */
38 #if (MQX_CPU == PSP_CPU_MK60D100M) || (MQX_CPU == PSP_CPU_MK60DF120M)
39 #define PN51X_EXT_INT_PIN (GPIO_PORT_A | GPIO_PIN26)
40 #define PN51X_EXT_MUX_IRQ LWGPIO_MUX_A26_GPIO
41 #elif (MQX_CPU == PSP_CPU_MK70F120M)
42 #error liutest do not support k70
43 #define PN51X_EXT_INT_PIN (GPIO_PORT_B | GPIO_PIN6)
44 #define PN51X_EXT_MUX_IRQ LWGPIO_MUX_B6_GPIO
45 #else
46 #error "#INT pin of PN51X not handled"
47 #endif
49 struct pn51x_common *pn51x_dev = NULL;
51 static void pn51x_interrupt(void * data);
52 static uint32_t _nfc_task_create(void * data);
53 static void _nfc_intr_task(void * data);
55 static int pn51x_reset(void)
57 if (!lwgpio_init(&pn51x_dev->reset_pin, PN51X_RESET_PIN, LWGPIO_DIR_OUTPUT, LWGPIO_VALUE_NOCHANGE)) {
58 printf("Initializing test pin GPIO as output failed.\n");
59 _task_block();
61 lwgpio_set_functionality(&pn51x_dev->reset_pin, PN51X_RESET_PIN_MUX_GPIO);
63 // pn51x hardware reset (spec P99 the signal must be LOW for at least 100 ns )
64 //---- 400us(min)--------
65 // |__________| low
67 lwgpio_set_value(&pn51x_dev->reset_pin,1);
68 OS_Time_delay(50);
69 lwgpio_set_value(&pn51x_dev->reset_pin,0);
70 OS_Time_delay(2);
71 lwgpio_set_value(&pn51x_dev->reset_pin,1);
73 return 0;
76 static int pn51x_init_extintr(void)
78 if (!lwgpio_init(&pn51x_dev->intr_pin, PN51X_EXT_INT_PIN, LWGPIO_DIR_INPUT, LWGPIO_VALUE_NOCHANGE)) {
79 printf("Initializing button 1 GPIO as input failed.\n");
80 _task_block();
83 lwgpio_set_functionality(&pn51x_dev->intr_pin, PN51X_EXT_MUX_IRQ);
84 lwgpio_set_attribute(&pn51x_dev->intr_pin, LWGPIO_ATTR_PULL_UP, LWGPIO_AVAL_ENABLE);
86 /* enable gpio functionality for given pin, react on falling edge */
87 if (!lwgpio_int_init(&pn51x_dev->intr_pin, LWGPIO_INT_MODE_FALLING)) {
88 printf("Initializing button GPIO for interrupt failed.\n");
89 _task_block();
92 /* install gpio interrupt service routine */
93 _int_install_isr(lwgpio_int_get_vector(&pn51x_dev->intr_pin), pn51x_interrupt, (void *) pn51x_dev);
94 /* set the interrupt level, and unmask the interrupt in interrupt controller*/
95 _bsp_int_init(lwgpio_int_get_vector(&pn51x_dev->intr_pin), PN51X_EXT_INTR_LEVEL, 0, TRUE); /* intr level is 5 */
96 /* enable interrupt on GPIO peripheral module */
97 lwgpio_int_enable(&pn51x_dev->intr_pin, TRUE);
99 return 0;
102 int pn51x_reg_write(uint8_t reg, uint8_t value)
104 uint8_t cmdBuf[2];
105 int ret;
106 // we removed this lock ,mqx spi io driver will do lock at internal !
107 //OS_Mutex_lock(pn51x_dev->pn51x_lock);
109 reg <<= 1;
110 CLEAR_BIT(reg, BIT(7));
111 cmdBuf[0] = reg;
112 cmdBuf[1] = value;
114 ret = nfc_spi_write(pn51x_dev->spi_handle, cmdBuf, 2);
115 if(ret < 0) {
116 pr_err("writting register to pn51x failed\n");
117 goto done;
120 ret = 0;
122 done:
123 //OS_Mutex_unlock(pn51x_dev->pn51x_lock);
124 return(0);
127 uint8_t pn51x_reg_read(uint8_t reg)
129 uint8_t tempReg;
130 uint8_t tempVal = 0x00;
131 int ret;
133 //OS_Mutex_lock(pn51x_dev->pn51x_lock);
134 tempReg = (reg << 1);
135 SET_BIT(tempReg, BIT(7));
137 ret = nfc_spi_write_then_read(pn51x_dev->spi_handle, &tempReg, 1, &tempVal, 1);
138 if(ret < 0) {
139 pr_err("reading register from pn51x failed\n");
142 //OS_Mutex_unlock(pn51x_dev->pn51x_lock);
143 return(tempVal);
146 void pn51x_reg_clear(uint8_t reg, uint8_t bitMask)
148 uint8_t tempValue;
150 tempValue = pn51x_reg_read(reg);
151 tempValue &= ~bitMask;
152 pn51x_reg_write(reg, tempValue);
155 void pn51x_reg_set(uint8_t reg, uint8_t bitMask)
157 uint8_t tempValue;
159 tempValue = pn51x_reg_read(reg);
160 tempValue |= bitMask;
161 pn51x_reg_write(reg, tempValue);
164 int pn51x_fifo_write(uint8_t *data, uint32_t len)
166 uint8_t buf[65]; /* */
167 int ret;
169 //OS_Mutex_lock(pn51x_dev->pn51x_lock);
171 if (len > PN51X_FIFO_MAX_DEEPTH) {
172 ret = -EINVAL;
173 goto done;
176 if(len <= 0) {
177 ret = 0;
178 goto done;
181 buf[0] = (FIFODataReg << 1) & 0x7E; // accroding to PN512: bit 7 = 0, write; bit 0 = 0
182 memcpy(buf + 1, data, len);
184 ret = nfc_spi_write(pn51x_dev->spi_handle, buf, len + 1);
185 if(ret < 0)
186 goto done;
188 ret = 0;
190 done:
191 //OS_Mutex_unlock(pn51x_dev->pn51x_lock);
192 return(ret);
195 int pn51x_fifo_read(uint8_t *data, uint32_t len)
197 uint32_t i;
198 uint8_t buf[64];
199 int ret;
200 //OS_Mutex_lock(pn51x_dev->pn51x_lock);
202 if (len > PN51X_FIFO_MAX_DEEPTH) {
203 ret = -EINVAL;
204 goto done;
207 if (len <= 0) {
208 ret = 0;
209 goto done;
212 memset(buf, (FIFODataReg << 1) | 0x80, len); // accroding to PN512: bit 7 = 1, read; bit 0 = 0
214 for(i = 0; i < len; i++) {
215 ret = nfc_spi_write_then_read(pn51x_dev->spi_handle, buf+i, 1, data+i, 1);
216 if(ret < 0) {
217 goto done;
220 ret = 0;
222 done:
223 //OS_Mutex_unlock(pn51x_dev->pn51x_lock);
224 return(ret);
228 void set_pn51x_timer(uint16_t timeOut)
230 pn51x_reg_write(TModeReg, 0x82); // TAuto=1,TAutoRestart=0,TPrescaler=677=2a5h
231 //printf("TModeReg 0x%x\n",pn51x_reg_read(TModeReg));
232 pn51x_reg_write(TPrescalerReg, 0xA5); // Indicate 100us per timeslot
233 pn51x_reg_write(TReloadVal_Hi, (uint8_t)(timeOut>>8)); //
234 pn51x_reg_write(TReloadVal_Lo, (uint8_t)timeOut); //
235 pn51x_reg_write(CommIRqReg, 0x01); // Clear the TimerIrq bit
238 void turn_on_antenna(void)
240 pn51x_reg_write(TxControlReg, 0x83);
243 void turn_off_antenna(void)
245 pn51x_reg_write(TxControlReg, 0x80);
248 void pn51x_process_done(struct pn51x_request *req)
250 struct pn51x_common *pn51x = container_of(req, struct pn51x_common, request);
252 pn51x_reg_write(CommandReg, CMD_IDLE);
253 pn51x_reg_set(ControlReg, TStopNow);
254 pn51x_reg_clear(TModeReg, TAuto);
255 pn51x_reg_write(CommIRqReg, 0x7F);
257 OS_Event_set(pn51x->pn51x_event,COMPLETE_EVENT);
260 void pn51x_process_request(struct pn51x_request *req)
262 struct pn51x_common *pn51x = container_of(req, struct pn51x_common, request);
264 pn51x->intr_enable_mask = IRqInv|ErrIEn|TimerIEn;
265 req->done = pn51x_process_done;
267 ASSERT(OS_Mutex_lock(pn51x->pn51x_lock) == OS_MUTEX_OK);
269 pn51x_reg_write(BitFramingReg, req->bit_frame);
270 pn51x_reg_write(FIFOLevelReg, FlushBuffer); // flush fifo
272 if(req->time_out) {
273 //if(req->timer_start_auto)
274 set_pn51x_timer((uint16_t)req->time_out);
275 if(req->timer_start_now)
276 pn51x_reg_set(ControlReg, TStartNow);
279 if(req->command == CMD_MFAUTHENT)
280 pn51x->intr_enable_mask |= IdleIEn;
281 #if 0
282 if(req->direction == RECEIVE) {
283 pn51x->intr_enable_mask |= RxIEn|HiAlertIEn;
284 pn51x_reg_set(REG_COMMIRQ, BIT_HIALERTIRQ);
286 else {
287 if(req->length > PN512_FIFO_MAX_FIFO_ALLOWED) {
288 pn51x_fifo_write(&req->buf[req->actual], PN51X_FIFO_MAX_FIFO_ALLOWED);
289 req->actual += PN51X_FIFO_MAX_FIFO_ALLOWED;
290 req->length -= PN51X_FIFO_MAX_FIFO_ALLOWED;
291 pn51x->intr_enable_mask |= LoAlertIEn;
292 pn51x_reg_set(REG_COMMIRQ, BIT_LOALERTIRQ);
294 else {
295 pn51x_fifo_write(&req->buf[req->actual], req->length);
296 req->actual = req->length = 0;
297 pn51x->intr_enable_mask |= TxIEn;
298 if(req->direction == TRANSCEIVE)
299 pn51x->intr_enable_mask |= RxIEn;
302 pn51x_reg_write(REG_COMMAND, req->command);
303 if(req->direction == TRANSCEIVE) {
304 pn51x_reg_set(REG_BITFRAMING, BIT_STARTSEND);
306 #else
307 if(req->direction == RECEIVE) {
308 pn51x->intr_enable_mask |= RxIEn|HiAlertIEn;
309 pn51x_reg_set(CommIRqReg, HiAlertIRq);
310 pn51x_reg_write(CommandReg, req->command);
312 else {
313 if(req->length > PN51X_FIFO_MAX_FIFO_ALLOWED) {
314 uint8_t temp_len;
316 pn51x_fifo_write(req->buf, PN51X_FIFO_MAX_FIFO_ALLOWED);
317 req->actual = PN51X_FIFO_MAX_FIFO_ALLOWED;
318 req->length -= PN51X_FIFO_MAX_FIFO_ALLOWED;
320 pn51x_reg_write(CommandReg, req->command);
322 pn51x_reg_set(BitFramingReg, StartSend);
324 while(req->length) {
325 if(pn51x_reg_read(FIFOLevelReg) < pn51x->water_level) {
326 pr_debug("water=%d\n", pn51x->water_level);
327 temp_len = (PN51X_FIFO_MAX_FIFO_ALLOWED - pn51x->water_level);
328 temp_len = req->length < temp_len ? req->length : temp_len;
329 pn51x_fifo_write(&req->buf[req->actual], temp_len);
330 req->actual += temp_len;
331 req->length -= temp_len;
335 req->actual = req->length = 0;
336 pn51x->intr_enable_mask |= TxIEn;
337 if(req->direction == TRANSCEIVE)
338 pn51x->intr_enable_mask |= RxIEn;
340 else {
341 pn51x_fifo_write(req->buf, req->length);
342 req->actual = req->length = 0;
344 pn51x->intr_enable_mask |= TxIEn;
345 if(req->direction == TRANSCEIVE)
346 pn51x->intr_enable_mask |= RxIEn;
348 pn51x_reg_write(CommandReg, req->command);
350 pn51x_reg_set(BitFramingReg, StartSend);
353 #endif
355 // enable pn51x irq
356 pn51x_reg_set(CommIEnReg, pn51x->intr_enable_mask);
358 // wait for event complete
359 if (MQX_OK != OS_Event_wait(pn51x->pn51x_event,COMPLETE_EVENT,0,0)) {
360 pr_err("wait complete event fail");
363 // disable pn51x irq
364 pn51x_reg_write(CommIEnReg, IRqInv);
366 ASSERT(OS_Mutex_unlock(pn51x_dev->pn51x_lock) == OS_MUTEX_OK);
370 static void pn51x_interrupt( void * data)
372 struct pn51x_common *pn51x = (struct pn51x_common *)data;
373 #ifdef HANDLE_INTR_IN_TASK
374 if(lwgpio_int_get_flag((LWGPIO_STRUCT_PTR) (&pn51x->intr_pin))) {
375 printf("pn51x ext intr\n");
376 OS_Event_set(pn51x->pn51x_event,EXT_INTR_EVENT);
377 lwgpio_int_clear_flag((LWGPIO_STRUCT_PTR) (&pn51x->intr_pin));
379 #else
380 struct pn51x_request *req = &pn51x->request;
381 uint8_t comm_irq;
383 pn51x_reg_write(CommIEnReg, IRqInv);
384 // printf("intr TModeReg 0x%x\n",pn51x_reg_read(TModeReg)); // test read reg in interrupt
386 comm_irq = pn51x_reg_read(CommIRqReg);
388 // reset irq mark
389 pn51x_reg_write(CommIRqReg, comm_irq);
390 comm_irq &= pn51x->intr_enable_mask;
392 // indicate the timer decrements the TimerValue Register to zero
393 if(comm_irq & TimerIRq) {
394 // stop timer // at done callback (ControlReg, TStopNow)
395 req->error_code = -ERROR_NOTAG;
396 req->done(req);
397 goto done;
400 // indicate any error bit in the Error Register is set
401 if(comm_irq & ErrIRq) {
402 uint8_t error = pn51x_reg_read(ErrorReg);
403 if(BITISSET(error, CollErr))
404 req->error_code = -ERROR_COLL; // collision detected
405 else {
406 if(BITISSET(error, ParityErr))
407 req->error_code = -ERROR_PARITY; // parity error
410 if(BITISSET(error, ProtocolErr))
411 req->error_code = -ERROR_PROTOCOL; // framing error
413 if(BITISSET(error, BufferOvfl) ) {
414 pn51x_reg_write(FIFOLevelReg, 0x80); // FIFO overflow
415 req->error_code = -ERROR_BUFOVFL;
418 if(BITISSET(error, CRCErr))
419 req->error_code = -ERROR_CRC;
422 // indicate the last bit of the transmitted data was sent out
423 if(comm_irq & TxIRq) {
424 if(!req->length) {
425 // transfer has complete
426 req->tx_done = 1;
427 if(req->direction == TRANSMIT) {
428 req->done(req);
429 goto done;
431 else { /* TRANSCEIVE or RECEIVE */
432 pn51x->intr_enable_mask &= ~(LoAlertIEn|TxIEn);
433 pn51x->intr_enable_mask |= RxIEn|HiAlertIEn;
434 pn51x_reg_write(CommIEnReg, pn51x->intr_enable_mask);
439 // indicate bit HiAlert in register Status1Reg is set
440 if(comm_irq & HiAlertIRq) {
441 uint8_t level;
442 if(!req->tx_done)
443 return;
444 // receiving stage
445 level = pn51x_reg_read(FIFOLevelReg);
446 pn51x_fifo_read(&req->buf[req->actual], level);
447 req->actual += level;
450 // indicate the receiver detects the end of a valid datastream
451 if(comm_irq & RxIRq) {
452 // receiving has complete
453 uint8_t level;
454 level = pn51x_reg_read(FIFOLevelReg);
455 pn51x->intr_enable_mask &= ~HiAlertIEn;
456 pn51x_reg_write(CommIEnReg, pn51x->intr_enable_mask);
457 req->rx_last_bits = pn51x_reg_read(ControlReg) & RxLastBitsMask;
459 pn51x_fifo_read(&req->buf[req->actual], level);
460 req->actual += level;
461 if(req->rx_last_bits)
462 req->bit_numbers = (req->actual - 1) * 8 + req->rx_last_bits;
463 else
464 req->bit_numbers = req->actual * 8;
466 req->done(req);
468 goto done;
471 if(comm_irq & IdleIRq) {
472 req->done(req);
473 goto done;
476 #if 0
477 // bit LoAlert in register Status1Reg is set
478 if(comm_irq & LoAlertIRq) {
479 UINT8 lim_len;
480 if(!req->tx_done) {
481 // transfer stage
482 lim_len = PN51X_FIFO_MAX_DEEPTH - pn51x->water_level;
483 if(req->length > lim_len) {
484 pn51x_fifo_write(&req->buf[req->actual], lim_len);
485 req->actual += lim_len;
486 req->length -= lim_len;
487 if((pn51x_reg_read(REG_STATUS2)&ModemStateMask) == 0x01) {
488 pn51x_reg_set(REG_BITFRAMING, BIT_STARTSEND);
491 else if(req->length) {
492 pn51x_fifo_write(&req->buf[req->actual], req->length);
493 req->actual = req->length = 0;
495 pn51x->intr_enable_mask &= ~LoAlertIEn;
496 pn51x->intr_enable_mask |= TxIEn;
497 if(req->direction == TRANSCEIVE)
498 pn51x->intr_enable_mask |= RxIEn;
500 pn51x_reg_write(CommIEnReg, pn51x->intr_enable_mask);
501 pn51x_reg_set(REG_BITFRAMING, BIT_STARTSEND);
505 #endif
507 done:
508 pn51x_reg_write(CommIEnReg, pn51x->intr_enable_mask);
509 #endif
512 #ifdef HANDLE_INTR_IN_TASK
513 static uint32_t _nfc_task_create(void * data)
515 _task_id task_id;
516 TASK_TEMPLATE_STRUCT task_template;
518 struct pn51x_common *pn51x = (struct pn51x_common *)data;
519 ASSERT(pn51x);
521 /* create task for processing interrupt deferred work */
522 task_template.TASK_TEMPLATE_INDEX = NFC_TASK_TEMPLATE_INDEX;
523 task_template.TASK_ADDRESS = NFC_TASK_ADDRESS;
524 task_template.TASK_STACKSIZE = NFC_TASK_STACKSIZE;
525 task_template.TASK_PRIORITY = NFC_TASK_PRIORITY;
526 task_template.TASK_NAME = NFC_TASK_NAME;
527 task_template.TASK_ATTRIBUTES = NFC_TASK_ATTRIBUTES;
528 task_template.CREATION_PARAMETER = (uint32_t)data;
529 task_template.DEFAULT_TIME_SLICE = NFC_TASK_DEFAULT_TIME_SLICE;
531 task_id = _task_create_blocked(0, 0, (uint32_t)&task_template);
533 if (task_id == 0) {
534 return MQX_ERROR;
536 pn51x->task_handle = task_id;
537 _task_ready(_task_get_td(task_id));
539 return MQX_OK;
542 static void _nfc_intr_task(void * data)
544 struct pn51x_common *pn51x = (struct pn51x_common *)data;
545 ASSERT(pn51x);
547 struct pn51x_request *req = &pn51x->request;
548 uint8_t comm_irq;
550 while (1) {
551 if (OS_EVENT_OK == OS_Event_wait(pn51x->pn51x_event,EXT_INTR_EVENT|CLOSE_TASK_EVENT,0,0)) {
553 pn51x_reg_write(CommIEnReg, IRqInv);
554 // printf("intr TModeReg 0x%x\n",pn51x_reg_read(TModeReg));
556 if(OS_Event_check_bit(pn51x->pn51x_event,CLOSE_TASK_EVENT)) {
557 printf("nfc task exited\n");
558 return;
561 comm_irq = pn51x_reg_read(CommIRqReg);
563 // reset irq mark
564 pn51x_reg_write(CommIRqReg, comm_irq);
565 comm_irq &= pn51x->intr_enable_mask;
567 // indicate the timer decrements the TimerValue Register to zero
568 if(comm_irq & TimerIRq) {
569 // stop timer // at done callback (ControlReg, TStopNow)
570 req->error_code = -ERROR_NOTAG;
571 req->done(req);
572 goto done;
575 // indicate any error bit in the Error Register is set
576 if(comm_irq & ErrIRq) {
577 uint8_t error = pn51x_reg_read(ErrorReg);
578 if(BITISSET(error, CollErr))
579 req->error_code = -ERROR_COLL; // collision detected
580 else {
581 if(BITISSET(error, ParityErr))
582 req->error_code = -ERROR_PARITY; // parity error
585 if(BITISSET(error, ProtocolErr))
586 req->error_code = -ERROR_PROTOCOL; // framing error
588 if(BITISSET(error, BufferOvfl) ) {
589 pn51x_reg_write(FIFOLevelReg, 0x80); // FIFO overflow
590 req->error_code = -ERROR_BUFOVFL;
593 if(BITISSET(error, CRCErr))
594 req->error_code = -ERROR_CRC;
597 // indicate the last bit of the transmitted data was sent out
598 if(comm_irq & TxIRq) {
599 if(!req->length) {
600 // transfer has complete
601 req->tx_done = 1;
602 if(req->direction == TRANSMIT) {
603 req->done(req);
604 goto done;
606 else { /* TRANSCEIVE or RECEIVE */
607 pn51x->intr_enable_mask &= ~(LoAlertIEn|TxIEn);
608 pn51x->intr_enable_mask |= RxIEn|HiAlertIEn;
609 pn51x_reg_write(CommIEnReg, pn51x->intr_enable_mask);
614 // indicate bit HiAlert in register Status1Reg is set
615 if(comm_irq & HiAlertIRq) {
616 uint8_t level;
617 if(!req->tx_done)
618 return;
619 // receiving stage
620 level = pn51x_reg_read(FIFOLevelReg);
621 pn51x_fifo_read(&req->buf[req->actual], level);
622 req->actual += level;
625 // indicate the receiver detects the end of a valid datastream
626 if(comm_irq & RxIRq) {
627 // receiving has complete
628 uint8_t level;
629 level = pn51x_reg_read(FIFOLevelReg);
630 pn51x->intr_enable_mask &= ~HiAlertIEn;
631 pn51x_reg_write(CommIEnReg, pn51x->intr_enable_mask);
632 req->rx_last_bits = pn51x_reg_read(ControlReg) & RxLastBitsMask;
634 pn51x_fifo_read(&req->buf[req->actual], level);
635 req->actual += level;
636 if(req->rx_last_bits)
637 req->bit_numbers = (req->actual - 1) * 8 + req->rx_last_bits;
638 else
639 req->bit_numbers = req->actual * 8;
641 req->done(req);
643 goto done;
646 if(comm_irq & IdleIRq) {
647 req->done(req);
648 goto done;
651 done:
652 pn51x_reg_write(CommIEnReg, pn51x->intr_enable_mask);
654 else {
655 pr_err("wait interrupt event fail\n");
659 #endif
661 int pn51x_init(struct pn51x_request **req)
663 int ret;
665 pn51x_dev = OS_Mem_alloc_zero(sizeof(struct pn51x_common));
666 if(!pn51x_dev) {
667 pr_err("fail to requesting memory for pn51x");
668 ret = -ENOMEM;
669 goto err1;
672 pn51x_dev->water_level = PN51X_FIFO_WATER_LEVEL;
674 pn51x_dev->pn51x_lock = OS_Mutex_create();
675 pn51x_dev->pn51x_event = OS_Event_create(1/* auto clear */);
677 ret = nfc_spi_init(&pn51x_dev->spi_handle);
678 if(ret)
679 goto err2;
681 ASSERT(pn51x_dev->spi_handle);
683 ret = pn51x_reg_read(VersionReg);
684 printf("pn51x version %d\n",ret);
686 // pn51x hardware reset (spec P99 the signal must be LOW for at least 100 ns )
687 //---- 400us(min)--------
688 // |__________| low
690 pn51x_reset();
693 pn51x_reg_write(CommIRqReg, 0x10);
694 // software reset pn512
695 ret = pn51x_reg_write(CommandReg, CMD_SOFTRESET);
696 if(ret < 0)
697 goto err2;
698 while((pn51x_reg_read(CommIRqReg)&IdleIRq) == 0); /* wait soft reset command finish.*/
700 //pn51x_reg_read(REG_MODE);
701 //pn51x_reg_read(REG_MODE);
702 ret = pn51x_reg_write(TxControlReg, 0x00); //Turn off the Antenna
703 if(ret < 0)
704 goto err2;
706 ret = pn51x_reg_write(CommandReg, 0x00); // Switch on the analog part of the receiver
707 if(ret < 0)
708 goto err2;
710 ret = pn51x_reg_write(ControlReg, 0x10); // Set PN512 in initiator mode
711 if(ret < 0)
712 goto err2;
714 ret = pn51x_reg_write(FIFOLevelReg, 0x80); // flush FIFO
715 if(ret < 0)
716 goto err2;
718 ret = pn51x_reg_write(WaterLevelReg, pn51x_dev->water_level); // set water level
719 if(ret < 0)
720 goto err2;
722 //while(1){turn_on_antenna();}
723 pn51x_reg_write(CommIEnReg, 0x80); // disable interrupts
724 pn51x_reg_write(DivIEnReg, 0x00);
725 pn51x_reg_write(CommIRqReg, 0x7F); // clean all the irq flag bits
726 pn51x_reg_write(DivIRqReg, 0x1F);
728 #ifdef HANDLE_INTR_IN_TASK
729 ASSERT(_nfc_task_create(pn51x_dev) == MQX_OK);
730 #endif
731 // pn51x ext pin interrupt init and enable it.
732 // TODO if error goto err4;
733 pn51x_init_extintr();
735 *req = &pn51x_dev->request;
737 // pn512_reg_read(REG_MODE);
738 return(0);
740 //err4:
741 //err3:
742 err2:
743 OS_Mem_free(pn51x_dev);
744 err1:
745 return ret;
748 int pn51x_uninit(void)
750 pn51x_reg_write(TxControlReg, 0x00); // turn off antenna
752 // disable ext pin interrupt
753 // TODO
754 #ifdef HANDLE_INTR_IN_TASK
755 //_nfc_task_destroy(pn51x_dev);
756 if(pn51x_dev->task_handle) {
757 OS_Event_set(pn51x_dev->pn51x_event ,CLOSE_TASK_EVENT);
758 OS_Time_delay(5);
759 OS_Task_delete(pn51x_dev->task_handle);
761 #endif
763 if(pn51x_dev->pn51x_lock) {
764 OS_Mutex_destroy(pn51x_dev->pn51x_lock);
765 pn51x_dev->pn51x_lock = NULL;
767 if(pn51x_dev->pn51x_event){
768 OS_Event_destroy(pn51x_dev->pn51x_event);
769 pn51x_dev->pn51x_event = NULL;
772 nfc_spi_uninit(pn51x_dev->spi_handle);
774 if(!pn51x_dev)
775 OS_Mem_free(pn51x_dev);
777 return(0);