extern bool Nrf24l::dataReady() // Checks if data is available for reading { // See note in getData() function - just checking RX_DR isn't good enough uint8_t status = getStatus(); // We can short circuit on RX_DR, but if it's not set, we still need // to check the FIFO for any pending packets if ( status & (1 << RX_DR) ) return 1; return !rxFifoEmpty(); }
extern bool Nrf24l::dataReady() // Checks if data is available for reading // 检测是否有可读的数据 { // See note in getData() function - just checking RX_DR isn't good enough // 查看 getData() 函数说明, // 只检查 RX_DR(接收数据中断,当接收到有效数据后置一) 并不是好办法。 uint8_t status = getStatus(); // We can short circuit on RX_DR, but if it's not set, we still need // to check the FIFO for any pending packets // 可以快速的检测 RX_DR ,但是如果没有检测到,还得检测FIFO是否空。 if ( status & (1 << RX_DR) ) return 1; return !rxFifoEmpty(); }
HRESULT BtI2cControllerClass::_performContiguousTransfers(I2cTransferClass* & pXfr) { ULONGLONG startWaitTicks = 0; ULONGLONG currentTicks = 0; I2cTransferClass* cmdXfr = nullptr; I2cTransferClass* readXfr = nullptr; PUCHAR readPtr = nullptr; HRESULT hr = S_OK; BOOL restart = FALSE; ULONG cmdDat; LONG cmdsOutstanding = 0; LONG readsOutstanding = 0; UCHAR outByte; UCHAR inByte; if (pXfr == nullptr) { hr = DMAP_E_DMAP_INTERNAL_ERROR; } if (SUCCEEDED(hr)) { // Calculate the command and read counts for the current sequence of // contiguous transfers in this transaction. hr = calculateCurrentCounts(pXfr, cmdsOutstanding, readsOutstanding); } // For each transfer in this section of the transaction: cmdXfr = pXfr; while (SUCCEEDED(hr) && (cmdsOutstanding > 0) && (cmdXfr != nullptr)) { // If this is the first read transfer in this sequence of transfers: if ((readXfr == nullptr) && cmdXfr->transferIsRead()) { // Indicate this is the transfer to read into. readXfr = cmdXfr; readXfr->resetRead(); readPtr = readXfr->getNextReadLocation(); } // Prepare to access the cmd buffer. cmdXfr->resetCmd(); // Signal a pre-restart if this transfer is marked for one. if (cmdXfr->preResart()) { restart = TRUE; } // For each byte in the transfer: while (SUCCEEDED(hr) && (cmdXfr->getNextCmd(outByte))) { // Wait for at least one empty space in the TX FIFO. while (txFifoFull()); // Issue the command. if (cmdXfr->transferIsRead()) { cmdDat = 0x100; // Build read command (data is ignored) } else { cmdDat = outByte; // Build write command with data byte } // If restart has been requested, signal a pre-RESTART. if (restart) { cmdDat = cmdDat | (1 << 10); restart = FALSE; // Only want to RESTART on first command of transfer } // If this is the last command before the end of the transaction or // before a callback, signal a STOP. if (cmdsOutstanding == 1) { cmdDat = cmdDat | (1 << 9); } // Issue the command. m_registers->IC_DATA_CMD.ALL_BITS = cmdDat; cmdsOutstanding--; hr = _handleErrors(); // Pull any available bytes out of the receive FIFO. while (SUCCEEDED(hr) && rxFifoNotEmtpy()) { // Read a byte from the I2C Controller. inByte = readByte(); readsOutstanding--; // Store the byte if we have a place for it. if (readPtr != nullptr) { *readPtr = inByte; // Figure out where the next byte should go. readPtr = readXfr->getNextReadLocation(); while ((readPtr == nullptr) && (readXfr->getNextTransfer() != nullptr)) { readXfr = readXfr->getNextTransfer(); readXfr->resetRead(); readPtr = readXfr->getNextReadLocation(); } } } } if (SUCCEEDED(hr)) { cmdXfr = cmdXfr->getNextTransfer(); } } // Complete any outstanding reads and wait for the TX FIFO to empty. startWaitTicks = GetTickCount64(); currentTicks = startWaitTicks; while (SUCCEEDED(hr) && ((readsOutstanding > 0) || !txFifoEmpty()) && !errorOccurred()) { // Pull any available bytes out of the receive FIFO. while (rxFifoNotEmtpy()) { // Read a byte from the I2C Controller. inByte = readByte(); readsOutstanding--; // Store the byte if we have a place for it. if (readPtr != nullptr) { *readPtr = inByte; // Figure out where the next byte should go. readPtr = readXfr->getNextReadLocation(); while ((readPtr == nullptr) && (readXfr->getNextTransfer() != nullptr)) { readXfr = readXfr->getNextTransfer(); readXfr->resetRead(); readPtr = readXfr->getNextReadLocation(); } } } // Wait up to to 100 milliseconds for transfers to happen. if (readsOutstanding > 0) { currentTicks = GetTickCount64(); if (((currentTicks - startWaitTicks) > 100) && rxFifoEmpty()) { hr = DMAP_E_I2C_READ_INCOMPLETE; } } } // Determine if an error occured on this transaction. if (SUCCEEDED(hr)) { hr = _handleErrors(); } // Pass the next transfer pointer back to the caller. pXfr = cmdXfr; // Record the read wait count for debugging purposes. if ((currentTicks - startWaitTicks) > m_maxWaitTicks) { m_maxWaitTicks = (ULONG)(currentTicks - startWaitTicks); } if (SUCCEEDED(hr)) { // Check for some catch-all errors. if (cmdsOutstanding > 0) { hr = DMAP_E_I2C_OPERATION_INCOMPLETE; } else if (readsOutstanding < 0) { hr = DMAP_E_I2C_EXTRA_DATA_RECEIVED; } else if (cmdsOutstanding < 0) { hr = DMAP_E_DMAP_INTERNAL_ERROR; } } return hr; }