static ssize_t pn544_ven_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { int retval = 0; NFC_DEBUG("%s: enter pn544_ven_store\n", __func__); if ('0' != buf[0]) { retval = gpio_direction_output(NFC_1V8EN,1); if (retval) { pr_err("%s: Failed to setup nfc_ven gpio %d. Code: %d.", __func__, NFC_1V8EN, retval); } ven_status = 1; } else { retval = gpio_direction_output(NFC_1V8EN,0); if (retval) { pr_err("%s: Failed to setup nfc_ven gpio %d. Code: %d.", __func__, NFC_1V8EN, retval); } ven_status = 0; } NFC_DEBUG("%s: exit pn544_ven_store\n", __func__); return count; }
s8 nfcTxNBytes(const u8 *buf, u8 bufSize, u8 perform_collision_avoidance) { s8 err = ERR_NONE; u8 regValue = 0; NFC_DEBUG("nfcTxNBytes(.buf="); NFC_DEBUG_HEX_DUMP(buf,bufSize); NFC_DEBUG(".bufSize=%hhx,.perform_collision_avoidance=%hhx)\n", bufSize, perform_collision_avoidance); err |= as3911ReadRegister(AS3911_REG_OP_CONTROL, ®Value); if (!(regValue & AS3911_REG_OP_CONTROL_tx_en)) { /* RF field is off, perform initial RF collision avoidance. */ u32 irqs = 0; err |= as3911EnableInterrupts(AS3911_IRQ_MASK_CAC | AS3911_IRQ_MASK_CAT); err |= as3911ExecuteCommand(AS3911_CMD_INITIAL_RF_COLLISION); irqs = as3911WaitForInterruptsTimed(AS3911_IRQ_MASK_CAC | AS3911_IRQ_MASK_CAT, NFC_RFCA_IRQ_TIMEOUT); err |= as3911DisableInterrupts(AS3911_IRQ_MASK_CAC | AS3911_IRQ_MASK_CAT); if (0 == irqs) { NFC_DEBUG("NFC_INITIAL_RFCA_IRQ_TIMEOUT expired\n"); return ERR_INTERNAL; } else if (AS3911_IRQ_MASK_CAC & irqs) { return ERR_RF_COLLISION; } } /* Setup NRT timer for rf response RF collision timeout. */ err |= as3911WriteRegister(AS3911_REG_NO_RESPONSE_TIMER1, RESPONSE_RFCA_NRT1); err |= as3911WriteRegister(AS3911_REG_NO_RESPONSE_TIMER2, RESPONSE_RFCA_NRT2); nfcPerformResponseCa = perform_collision_avoidance; as3911PrepareReceive(TRUE); err |= as3911TxNBytes(buf, bufSize, 0, AS3911_TX_FLAG_CRC); nfcRxBufferInPtr = nfcRxBuffer; nfcTaskStatus = NFC_TASK_WAIT_FOR_EON; if (ERR_NONE != err) return ERR_IO; else return ERR_NONE; }
static int pn544_dev_open(struct inode *inode, struct file *filp) { struct pn544_dev *pn544_dev = container_of(filp->private_data, struct pn544_dev, pn544_device); NFC_DEBUG("%s:enter pn544_dev_open\n", __func__); filp->private_data = pn544_dev; pr_info("%s : %d,%d\n", __func__, imajor(inode), iminor(inode)); NFC_DEBUG("%s:exit pn544_dev_open\n", __func__); return 0; }
s8 nfcStartInitialTargetRx() { s8 err = ERR_NONE; NFC_DEBUG("nfcStartInitialTargetRx()\n"); if ( (NFC_TASK_TRANSMITTING == nfcTaskStatus) || (NFC_TASK_RX_IN_PROGRESS == nfcTaskStatus)) return ERR_BUSY; err |= as3911ExecuteCommand(AS3911_CMD_CLEAR_FIFO); /* Enter low power bitrate detection mode. */ err |= as3911WriteRegister(AS3911_REG_MODE, 0x80); /* Turn off the chip. */ err |= as3911ModifyRegister(AS3911_REG_OP_CONTROL, AS3911_REG_OP_CONTROL_en | AS3911_REG_OP_CONTROL_rx_en | AS3911_REG_OP_CONTROL_tx_en, 0x00); if (ERR_NONE != err) return ERR_IO; nfcLowPowerMode = TRUE; nfcPerformResponseCa = TRUE; nfcRxBufferInPtr = nfcRxBuffer; nfcRxError = ERR_NONE; nfcTaskStatus = NFC_TASK_WAIT_FOR_EON; return ERR_NONE; }
s8 nfcDeinitialize() { s8 err = ERR_NONE; u8 regOpControl = 0; NFC_DEBUG("nfcDeinitialize()\n"); nfcTaskStatus = NFC_TASK_INACTIVE; err |= as3911ReadRegister(AS3911_REG_OP_CONTROL, ®OpControl); if (!(AS3911_REG_OP_CONTROL_en & regOpControl)) { u32 oscIrqs = as3911GetInterrupt(AS3911_IRQ_MASK_OSC); as3911EnableInterrupts(AS3911_IRQ_MASK_OSC); err |= as3911ModifyRegister(AS3911_REG_OP_CONTROL, AS3911_REG_OP_CONTROL_en | AS3911_REG_OP_CONTROL_rx_en | AS3911_REG_OP_CONTROL_tx_en, AS3911_REG_OP_CONTROL_en | AS3911_REG_OP_CONTROL_rx_en); /* Wait for oscillators to start. */ oscIrqs = as3911WaitForInterruptsTimed(AS3911_IRQ_MASK_OSC, NFC_OSC_IRQ_TIMEOUT); as3911DisableInterrupts(AS3911_IRQ_MASK_OSC); if (0 == oscIrqs) { NFC_DEBUG("NFC_OSC_IRQ_TIMEOUT expired\n"); return ERR_INTERNAL; } } err |= as3911SetBitrate(0,0); /* Restore old settings. */ err |= as3911WriteRegister(AS3911_REG_FIELD_THRESHOLD, nfcSavedSettings.regFieldThreshold); err |= as3911WriteRegister(AS3911_REG_RX_CONF3, nfcSavedSettings.regRxConf3); err |= as3911WriteRegister(AS3911_REG_GPT_CONTROL, 0); /* Turn off reader field. */ err |= as3911ModifyRegister(AS3911_REG_OP_CONTROL, AS3911_REG_OP_CONTROL_tx_en, 0); if (ERR_NONE != err) return ERR_IO; else return ERR_NONE; }
s8 nfcRxNBytes(u8 *buf, u8 bufsize, u8 *actlen) { NFC_DEBUG("nfcRxNBytes( .bufSize=%hhx)\n"); *actlen = 0; if (NFC_TASK_RX_DONE == nfcTaskStatus) { *actlen = nfcRxBufferInPtr - nfcRxBuffer - 2; memcpy(buf, nfcRxBuffer, *actlen); return nfcRxError; } return ERR_BUSY; }
static ssize_t pn544_dev_write(struct file *filp, const char __user *buf, size_t count, loff_t *offset) { struct pn544_dev *pn544_dev; char tmp[MAX_BUFFER_SIZE]; int ret; int calc = 0; pn544_dev = filp->private_data; if (count > MAX_BUFFER_SIZE) count = MAX_BUFFER_SIZE; if (copy_from_user(tmp, buf, count)) { pr_err("%s : failed to copy from user space\n", __func__); return -EFAULT; } NFC_DEBUG("%s : writing %zu bytes.\n", __func__, count); /* Write data */ while(calc <3) { calc ++; ret = i2c_master_send(pn544_dev->client, tmp, count); if (ret != count) { pr_info("%s : send data try =%d returned %d\n", __func__,calc,ret); msleep(10); continue; } else break; } if (calc ==3) { pr_err("%s : i2c_master_send returned %d\n", __func__, ret); ret = -EIO; } return ret; }
s8 nfcSwitchToRx(u8 perform_collision_avoidance) { u8 err = ERR_NONE; NFC_DEBUG("nfcSwitchToRx()"); if (!(NFC_TASK_RX_DONE == nfcTaskStatus)) return ERR_IO; /* Setup NRT timer for rf response RF collision timeout. */ err |= as3911WriteRegister(AS3911_REG_NO_RESPONSE_TIMER1, RESPONSE_RFCA_NRT1); err |= as3911WriteRegister(AS3911_REG_NO_RESPONSE_TIMER2, RESPONSE_RFCA_NRT2); /* Prepare data reception. */ nfcPerformResponseCa = perform_collision_avoidance; as3911PrepareReceive(TRUE); /* Enter low power bitrate detection mode. */ err |= as3911WriteRegister(AS3911_REG_MODE, 0x80); /* Start the NRE timer. */ err |= as3911ExecuteCommand(AS3911_CMD_START_NO_RESPONSE_TIMER); /* Disable the RF field manually. */ err |= as3911ModifyRegister(AS3911_REG_OP_CONTROL, AS3911_REG_OP_CONTROL_tx_en, 0); nfcRxBufferInPtr = nfcRxBuffer; nfcTaskStatus = NFC_TASK_WAIT_FOR_EON; while (nfcTaskStatus != NFC_TASK_RX_DONE) err |= nfcReceptionTask(); if (ERR_NONE != err) return ERR_IO; else return ERR_NONE; }
static ssize_t pn544_dev_read(struct file *filp, char __user *buf, size_t count, loff_t *offset) { struct pn544_dev *pn544_dev = filp->private_data; char tmp[MAX_BUFFER_SIZE]; int ret, i; int calc = 0; if (count > MAX_BUFFER_SIZE) count = MAX_BUFFER_SIZE; NFC_DEBUG("%s : reading %zu bytes.\n", __func__, count); mutex_lock(&pn544_dev->read_mutex); wake_lock_timeout(&wlock_read, 1 * HZ); NFC_DEBUG("%s : start to gpio_get_value with got value: %d\n", __func__, gpio_get_value(pn544_dev->irq_gpio)); if (!gpio_get_value(pn544_dev->irq_gpio)) { if (filp->f_flags & O_NONBLOCK) { NFC_DEBUG("flip->f_flags=%u\n",filp->f_flags); ret = -EAGAIN; goto fail; } pn544_dev->irq_enabled = true; NFC_DEBUG("%s : start to enable_irq.\n", __func__); enable_irq(pn544_dev->client->irq); NFC_DEBUG("%s : start to wait_event_interruptible.\n", __func__); ret = wait_event_interruptible(pn544_dev->read_wq, gpio_get_value(pn544_dev->irq_gpio)); NFC_DEBUG("%s : end to pn544_disable_irq, with ret: %d.\n", __func__, ret); pn544_disable_irq(pn544_dev); if (ret) goto fail; } NFC_DEBUG("%s : start to i2c_master_recv.\n", __func__); /* Read data */ while(calc <3) { calc ++; ret = i2c_master_recv(pn544_dev->client, tmp, count); if (ret < 0) { pr_info("%s : read data try =%d returned %d\n", __func__,calc,ret); msleep(10); continue; } else break; } if (calc ==3) { pr_err("%s : i2c_master_recv returned %d\n", __func__, ret); ret = -EIO; } mutex_unlock(&pn544_dev->read_mutex); NFC_DEBUG("%s : end to i2c_master_recv, with the ret: %d.\n", __func__, ret); for(i=0; i<count; i++) { NFC_DEBUG("%s : read %x.\n", __func__, tmp[i]); } if (ret < 0) { pr_err("%s: i2c_master_recv returned %d\n", __func__, ret); return ret; } if (ret > count) { pr_err("%s: received too many bytes from i2c (%d)\n", __func__, ret); return -EIO; } if (copy_to_user(buf, tmp, ret)) { pr_err("%s : failed to copy to user space\n", __func__); return -EFAULT; } return ret; fail: mutex_unlock(&pn544_dev->read_mutex); return ret; }
static int check_pn544(struct i2c_client *client) { int ret; int count = 0; int calc = 0; int check_pn544_result = 0; const char host_to_pn544[8] = {0x05, 0xF9, 0x04, 0x00, 0xC3, 0xe5}; const char check_from_pn544[8] = {0x03,0xE6,0x17,0xA7}; char pn544_to_host[8]; const char cmd_fwdld_first[4] = {0x01, 0x00, 0x00}; struct pn544_i2c_platform_data *platform_data; platform_data = client->dev.platform_data; NFC_DEBUG("------enter check pn544-----\n"); for(count = 0; count < 3; count++) { ret = i2c_master_send(client, &host_to_pn544, 6); NFC_DEBUG("%s:enter pn544 I2C\n", __func__); if (ret < 0) { pr_err("%s:pn544_i2c_write failed\n", __func__); msleep(10); continue; } pr_err("pn544_i2c_write: %x, %x, %x, %x, %x, %x \n", host_to_pn544[0],host_to_pn544[1], host_to_pn544[2],host_to_pn544[3],host_to_pn544[4],host_to_pn544[5]); ret = i2c_master_recv(client, &pn544_to_host, 4); if (ret < 0) { pr_err("%s:pn544_i2c_read failed\n", __func__); msleep(10); continue; } pr_err("pn544_i2c_read: %x,%x,%x,%x \n", pn544_to_host[0],pn544_to_host[1], pn544_to_host[2],pn544_to_host[3]); if(!((pn544_to_host[0]== check_from_pn544[0])&&(pn544_to_host[1]== check_from_pn544[1]) &&(pn544_to_host[2]== check_from_pn544[2])&&(pn544_to_host[3]== check_from_pn544[3]))) { pr_err("%s : pn544 device check failed.\n", __func__); msleep(10); ret = -ENODEV; continue; } check_pn544_result = 1; break; } if ((1 == check_pn544_result) ||(pn544_to_host[0] == 0x51)) { pr_err("%s, pn544 check successfully.\n", __func__); ret = 0; goto exit; } for(calc = 0; calc < 3; calc++) { pr_info("%s:enter fw download mode\n", __func__); gpio_set_value(platform_data->ven_gpio, 1); gpio_set_value(platform_data->firm_gpio, 1); msleep(20); gpio_set_value(platform_data->ven_gpio, 0); msleep(60); gpio_set_value(platform_data->ven_gpio, 1); msleep(20); pr_info("%s:send fw download cmd for check pn544\n", __func__); ret = i2c_master_send(client, &cmd_fwdld_first, 3); if (ret < 0) { pr_err("%s:pn544_i2c_write download cmd failed:%d.\n", __func__,calc); continue; } pr_info("%s:exit firmware download for check pn544 successfully\n", __func__); gpio_set_value(platform_data->firm_gpio, 0); gpio_set_value(platform_data->ven_gpio, 1); msleep(20); gpio_set_value(platform_data->ven_gpio, 0); msleep(60); gpio_set_value(platform_data->ven_gpio, 1); msleep(20); break; } exit: return ret; }
s8 nfcReceptionTask() { s8 err = ERR_NONE; u32 irqs = 0; if (NFC_TASK_INACTIVE == nfcTaskStatus) return ERR_NONE; irqs = as3911GetInterrupt(AS3911_IRQ_MASK_RXS | AS3911_IRQ_MASK_RXE | AS3911_IRQ_MASK_FWL | AS3911_IRQ_MASK_NRE | AS3911_IRQ_MASK_NFCT | AS3911_IRQ_MASK_EON | AS3911_IRQ_MASK_EOF); if (AS3911_IRQ_MASK_EON & irqs) { if (NFC_TASK_WAIT_FOR_EON == nfcTaskStatus) { if (nfcLowPowerMode) { nfcLowPowerMode = FALSE; /* Clear oscillator on interrupt flag. */ u32 oscIrqs = as3911GetInterrupt(AS3911_IRQ_MASK_OSC); as3911EnableInterrupts(AS3911_IRQ_MASK_OSC); err |= as3911ModifyRegister(AS3911_REG_OP_CONTROL, AS3911_REG_OP_CONTROL_en | AS3911_REG_OP_CONTROL_rx_en | AS3911_REG_OP_CONTROL_tx_en, AS3911_REG_OP_CONTROL_en | AS3911_REG_OP_CONTROL_rx_en); /* Wait for oscillators to start. */ oscIrqs = as3911WaitForInterruptsTimed(AS3911_IRQ_MASK_OSC, NFC_OSC_IRQ_TIMEOUT); as3911DisableInterrupts(AS3911_IRQ_MASK_OSC); if (0 == oscIrqs) { NFC_DEBUG("NFC_OSC_IRQ_TIMEOUT expired\n"); return ERR_INTERNAL; } /* Switch to normal target mode. */ // err |= as3911WriteRegister(AS3911_REG_MODE, 0x88); } err |= as3911ExecuteCommand(AS3911_CMD_UNMASK_RECEIVE_DATA); /* The no response timer is stopped on an EON event. We therefore * restart the timer to be able to use it as a message timeout timer. * In addition to its NFC-P2P mode default usage as an external field on * timeout timer. */ err |= as3911WriteRegister(AS3911_REG_NO_RESPONSE_TIMER1, TIMEOUT_NRT1); err |= as3911WriteRegister(AS3911_REG_NO_RESPONSE_TIMER2, TIMEOUT_NRT2); err |= as3911ExecuteCommand(AS3911_CMD_START_NO_RESPONSE_TIMER); nfcTaskStatus = NFC_TASK_WAIT_FOR_RXS; } } if (AS3911_IRQ_MASK_RXS & irqs) { nfcRxBufferInPtr = nfcRxBuffer; nfcTaskStatus = NFC_TASK_RX_IN_PROGRESS; } if (AS3911_IRQ_MASK_FWL & irqs) { err |= as3911ReadFifo(nfcRxBufferInPtr, NFC_FIFO_READ_SIZE); nfcRxBufferInPtr += NFC_FIFO_READ_SIZE; } if (AS3911_IRQ_MASK_RXE & irqs) { /* Reading the FIFO is postponed until the response collision avoidance has been performed. */ nfcTaskStatus = NFC_TASK_WAIT_FOR_EOF; } if (AS3911_IRQ_MASK_NFCT & irqs) { nfcBitrateDetected = TRUE; } if (AS3911_IRQ_MASK_NRE & irqs) { if ( (NFC_TASK_WAIT_FOR_EON == nfcTaskStatus) || (NFC_TASK_WAIT_FOR_RXS == nfcTaskStatus)) { nfcTaskStatus = NFC_TASK_RX_DONE; nfcRxError = ERR_TIMEOUT; } } if (AS3911_IRQ_MASK_EOF & irqs) { /* A bitrate detection event can only happen when we are in the bitrate * detection target mode. Thus, if such an event has happened during the * reception (the irq happens shortly after the RxS irq) we need to switch * back to normal nfc mode. */ if ( (NFC_TASK_WAIT_FOR_EOF == nfcTaskStatus) && nfcBitrateDetected) { err |= as3911ExecuteCommand(AS3911_CMD_NORMAL_NFC_MODE); } nfcBitrateDetected = FALSE; if ( (NFC_TASK_WAIT_FOR_EOF == nfcTaskStatus) && nfcPerformResponseCa) { nfcPerformResponseCa = FALSE; err |= as3911EnableInterrupts(AS3911_IRQ_MASK_CAC | AS3911_IRQ_MASK_CAT); err |= as3911ExecuteCommand(AS3911_CMD_RESPONSE_RF_COLLISION_0); irqs = as3911WaitForInterruptsTimed(AS3911_IRQ_MASK_CAC | AS3911_IRQ_MASK_CAT, NFC_RFCA_IRQ_TIMEOUT); err |= as3911DisableInterrupts(AS3911_IRQ_MASK_CAC | AS3911_IRQ_MASK_CAT); if (0 == irqs) { NFC_DEBUG("NFC_RFCA_IRQ_TIMEOUT expired\n"); nfcTaskStatus = NFC_TASK_RX_DONE; nfcRxError = ERR_INTERNAL; } else if (AS3911_IRQ_MASK_CAC & irqs) { nfcTaskStatus = NFC_TASK_RX_DONE; nfcRxError = ERR_RF_COLLISION; } } if ( (NFC_TASK_WAIT_FOR_RXS == nfcTaskStatus) || (NFC_TASK_RX_IN_PROGRESS == nfcTaskStatus)) { nfcTaskStatus = NFC_TASK_RX_DONE; nfcRxError = ERR_TIMEOUT; } if (NFC_TASK_WAIT_FOR_EOF == nfcTaskStatus) { u8 fifoReadSize; err |= as3911ReadRegister(AS3911_REG_FIFO_RX_STATUS1, &fifoReadSize); as3911ReadFifo(nfcRxBufferInPtr, fifoReadSize); nfcRxBufferInPtr += fifoReadSize; nfcTaskStatus = NFC_TASK_RX_DONE; irqs = as3911GetInterrupt(AS3911_IRQ_MASK_CRC | AS3911_IRQ_MASK_PAR | AS3911_IRQ_MASK_ERR2 | AS3911_IRQ_MASK_ERR1); if (irqs & AS3911_IRQ_MASK_CRC) nfcRxError = ERR_CRC; else if (irqs & AS3911_IRQ_MASK_PAR) nfcRxError = ERR_PAR; else if ((irqs & AS3911_IRQ_MASK_ERR1) || (irqs & AS3911_IRQ_MASK_ERR2)) nfcRxError = ERR_FRAMING; else if (0 != irqs) nfcRxError = ERR_FRAMING; else nfcRxError = ERR_NONE; /* Stop NRE timer via a clear fifo cmd. */ as3911ExecuteCommand(AS3911_CMD_CLEAR_FIFO); /* Clear pending NRE timer events. */ as3911GetInterrupt(AS3911_IRQ_MASK_NRE); irqs &= ~AS3911_IRQ_MASK_NRE; } } if (ERR_NONE != err) return ERR_IO; else return ERR_NONE; }
s8 nfcInitialize(u8 is_active, u8 is_initiator, u8 bitrate) { s8 err = ERR_NONE; u8 regOpControl = 0; NFC_DEBUG("nfcInitialize(.is_active=%hhx,.is_initiator=%hhx,.bitrate=%hhx)\n", is_active, is_initiator, bitrate); /* Passive mode is currently not supported by this NFC module. */ if (!is_active) return ERR_PARAM; err |= as3911ReadRegister(AS3911_REG_OP_CONTROL, ®OpControl); if (!(AS3911_REG_OP_CONTROL_en & regOpControl)) { u32 oscIrqs = as3911GetInterrupt(AS3911_IRQ_MASK_OSC); as3911EnableInterrupts(AS3911_IRQ_MASK_OSC); err |= as3911ModifyRegister(AS3911_REG_OP_CONTROL, AS3911_REG_OP_CONTROL_en | AS3911_REG_OP_CONTROL_rx_en | AS3911_REG_OP_CONTROL_tx_en, AS3911_REG_OP_CONTROL_en | AS3911_REG_OP_CONTROL_rx_en); /* Wait for oscillators to start. */ oscIrqs = as3911WaitForInterruptsTimed(AS3911_IRQ_MASK_OSC, NFC_OSC_IRQ_TIMEOUT); as3911DisableInterrupts(AS3911_IRQ_MASK_OSC); if (0 == oscIrqs) { NFC_DEBUG("NFC_OSC_IRQ_TIMEOUT expired\n"); return ERR_INTERNAL; } } /* Stop ongoing operations. */ err |= as3911ExecuteCommand(AS3911_CMD_CLEAR_FIFO); /* Enable receiver, turn off RF field. */ err |= as3911ModifyRegister( AS3911_REG_OP_CONTROL, AS3911_REG_OP_CONTROL_rx_en | AS3911_REG_OP_CONTROL_tx_en, AS3911_REG_OP_CONTROL_rx_en); if (is_initiator) /* NFCIP1 active communication initiator mode. */ err |= as3911WriteRegister(AS3911_REG_MODE, 0x00); else /* NFCIP1 active communication fixed bitrate target mode. */ err |= as3911WriteRegister(AS3911_REG_MODE, 0x88); /* Peer detection threshold: 105mV * Collision Avoidance Threshold: 105mV */ err |= as3911ReadRegister(AS3911_REG_FIELD_THRESHOLD, &nfcSavedSettings.regFieldThreshold); err |= as3911WriteRegister(AS3911_REG_FIELD_THRESHOLD, 0x11); /* Silicon v2 bug: we have to always receive crc bytes */ err |= as3911ModifyRegister(AS3911_REG_AUX, AS3911_REG_AUX_crc_2_fifo, AS3911_REG_AUX_crc_2_fifo); /* Start the GPT after end of TX, EMV no response timer mode, no response timer set in 4096 fc intervalls. */ err |= as3911WriteRegister(AS3911_REG_GPT_CONTROL, 0x63); /* The field is turned off 37.76µs after the end of the transmission. */ err |= as3911WriteRegister(AS3911_REG_GPT1, 0x00); err |= as3911WriteRegister(AS3911_REG_GPT2, 0x40); /* Mask receive timer. */ err |= as3911WriteRegister(AS3911_REG_MASK_RX_TIMER, 0x01); /* Reduce first stage gain for 106 kBit/s bitrate. */ err |= as3911ReadRegister(AS3911_REG_RX_CONF3, &nfcSavedSettings.regRxConf3); if (0x00 == bitrate) err |= as3911ModifyRegister(AS3911_REG_RX_CONF3, 0xE0, 0xC0); else err |= as3911ModifyRegister(AS3911_REG_RX_CONF3, 0xE0, 0x00); if (bitrate > 0x02) return ERR_PARAM; err |= as3911SetBitrate(bitrate,bitrate); if (bitrate > 0x00) { /* Set to 25% AM modulation. * modulation index: 25% * a/b = 1.66666666 * a/b = b1.101010 */ err |= as3911WriteRegister(AS3911_REG_AM_MOD_DEPTH_CONTROL, 0x54); err |= as3911CalibrateModulationDepth(NULL); } err |= as3911WriteRegister(AS3911_REG_NO_RESPONSE_TIMER1, TIMEOUT_NRT1); err |= as3911WriteRegister(AS3911_REG_NO_RESPONSE_TIMER2, TIMEOUT_NRT2); err |= as3911ClearInterrupts(); err |= as3911EnableInterrupts(AS3911_IRQ_MASK_RXS | AS3911_IRQ_MASK_RXE | AS3911_IRQ_MASK_FWL | AS3911_IRQ_MASK_NRE | AS3911_IRQ_MASK_NFCT | AS3911_IRQ_MASK_EOF | AS3911_IRQ_MASK_EON | AS3911_IRQ_MASK_CRC | AS3911_IRQ_MASK_PAR | AS3911_IRQ_MASK_ERR2 | AS3911_IRQ_MASK_ERR1); if (is_initiator) { nfcTaskStatus = NFC_TASK_TRANSMITTING; nfcBitrateDetected = FALSE; nfcLowPowerMode = FALSE; nfcPerformResponseCa = FALSE; nfcRxBufferInPtr = nfcRxBuffer; nfcRxError = ERR_NONE; } else { nfcTaskStatus = NFC_TASK_INACTIVE; nfcBitrateDetected = FALSE; nfcLowPowerMode = FALSE; nfcPerformResponseCa = FALSE; nfcRxBufferInPtr = nfcRxBuffer; nfcRxError = ERR_NONE; } if (ERR_NONE != err) return ERR_IO; else return ERR_NONE; }