// Start trace performance monitoring size_t AwsXcl::xclPerfMonStartTrace(xclPerfMonType type, uint32_t startTrigger) { if (mLogStream.is_open()) { mLogStream << __func__ << ", " << std::this_thread::get_id() << ", " << type << ", " << startTrigger << ", Start device tracing..." << std::endl; } size_t size = 0; uint32_t regValue; uint64_t ctrlAddress = getPerfMonBaseAddress(type) + XAPM_CTL_OFFSET; xclAddressSpace addressSpace = (type == XCL_PERF_MON_OCL_REGION) ? XCL_ADDR_KERNEL_CTRL : XCL_ADDR_SPACE_DEVICE_PERFMON; // 1. Reset APM trace stream FIFO size += xclRead(addressSpace, ctrlAddress, ®Value, 4); regValue = regValue | XAPM_CR_FIFO_RESET_MASK; size += xclWrite(addressSpace, ctrlAddress, ®Value, 4); regValue = regValue & ~(XAPM_CR_FIFO_RESET_MASK); size += xclWrite(addressSpace, ctrlAddress, ®Value, 4); // 2. Start APM event log regValue = regValue | XAPM_CR_EVENTLOG_ENABLE_MASK; size += xclWrite(addressSpace, ctrlAddress, ®Value, 4); // 3. Reset trace FIFOs size += resetFifos(type); // 4. Send host timestamps to target device size += xclPerfMonClockTraining(type); // 5. Disable host monitoring on slot 1 // TODO: replace check for value of startTrigger (temp way // of keeping slot 1 enabled in 06_perfmon test) if ((type == XCL_PERF_MON_MEMORY) && (startTrigger == 0)) { regValue = 0xFFFFFF0F; uint64_t enableTraceAddress = getPerfMonBaseAddress(type) + XAPM_ENT_OFFSET; size += xclWrite(addressSpace, enableTraceAddress, ®Value, 4); } // 6. Write to event trace trigger register // TODO: add support for triggering in device here //size += xclWrite(addressSpace, TBD, &startTrigger, 4); return size; }
// Stop trace performance monitoring size_t AwsXcl::xclPerfMonStopTrace(xclPerfMonType type) { if (mLogStream.is_open()) { mLogStream << __func__ << ", " << std::this_thread::get_id() << ", " << type << ", Stop and reset device tracing..." << std::endl; } size_t size = 0; uint32_t regValue; uint64_t ctrlAddress = getPerfMonBaseAddress(type) + XAPM_CTL_OFFSET; xclAddressSpace addressSpace = (type == XCL_PERF_MON_OCL_REGION) ? XCL_ADDR_KERNEL_CTRL : XCL_ADDR_SPACE_DEVICE_PERFMON; // 1. Stop APM event log and metric counters size += xclRead(addressSpace, ctrlAddress, ®Value, 4); regValue = regValue & ~(XAPM_CR_EVENTLOG_ENABLE_MASK); size += xclWrite(addressSpace, ctrlAddress, ®Value, 4); size += resetFifos(type); return size; }
// C++ level interrupt handler for this instance void RF22::handleInterrupt() { uint8_t _lastInterruptFlags[2]; // Read the interrupt flags which clears the interrupt spiBurstRead(RF22_REG_03_INTERRUPT_STATUS1, _lastInterruptFlags, 2); #if 0 // Caution: Serial printing in this interrupt routine can cause mysterious crashes Serial.print("interrupt "); Serial.print(_lastInterruptFlags[0], HEX); Serial.print(" "); Serial.println(_lastInterruptFlags[1], HEX); if (_lastInterruptFlags[0] == 0 && _lastInterruptFlags[1] == 0) Serial.println("FUNNY: no interrupt!"); #endif #if 0 // TESTING: fake an RF22_IFFERROR static int counter = 0; if (_lastInterruptFlags[0] & RF22_IPKSENT && counter++ == 10) { _lastInterruptFlags[0] = RF22_IFFERROR; counter = 0; } #endif if (_lastInterruptFlags[0] & RF22_IFFERROR) { // Serial.println("IFFERROR"); resetFifos(); // Clears the interrupt if (_mode == RF22_MODE_TX) restartTransmit(); else if (_mode == RF22_MODE_RX) clearRxBuf(); } // Caution, any delay here may cause a FF underflow or overflow if (_lastInterruptFlags[0] & RF22_ITXFFAEM) { // See if more data has to be loaded into the Tx FIFO sendNextFragment(); // Serial.println("ITXFFAEM"); } if (_lastInterruptFlags[0] & RF22_IRXFFAFULL) { // Caution, any delay here may cause a FF overflow // Read some data from the Rx FIFO readNextFragment(); // Serial.println("IRXFFAFULL"); } if (_lastInterruptFlags[0] & RF22_IEXT) { // This is not enabled by the base code, but users may want to enable it handleExternalInterrupt(); // Serial.println("IEXT"); } if (_lastInterruptFlags[1] & RF22_IWUT) { // This is not enabled by the base code, but users may want to enable it handleWakeupTimerInterrupt(); // Serial.println("IWUT"); } if (_lastInterruptFlags[0] & RF22_IPKSENT) { // Serial.println("IPKSENT"); _txGood++; // Transmission does not automatically clear the tx buffer. // Could retransmit if we wanted // RF22 transitions automatically to Idle _mode = RF22_MODE_IDLE; } if (_lastInterruptFlags[0] & RF22_IPKVALID) { uint8_t len = spiRead(RF22_REG_4B_RECEIVED_PACKET_LENGTH); // Serial.println("IPKVALID"); // Serial.println(len); // Serial.println(_bufLen); // May have already read one or more fragments // Get any remaining unread octets, based on the expected length // First make sure we dont overflow the buffer in the case of a stupid length // or partial bad receives if ( len > RF22_MAX_MESSAGE_LEN || len < _bufLen) { _rxBad++; _mode = RF22_MODE_IDLE; clearRxBuf(); return; // Hmmm receiver buffer overflow. } spiBurstRead(RF22_REG_7F_FIFO_ACCESS, _buf + _bufLen, len - _bufLen); _rxGood++; _bufLen = len; _mode = RF22_MODE_IDLE; _rxBufValid = true; } if (_lastInterruptFlags[0] & RF22_ICRCERROR) { // Serial.println("ICRCERR"); _rxBad++; clearRxBuf(); resetRxFifo(); _mode = RF22_MODE_IDLE; setModeRx(); // Keep trying } if (_lastInterruptFlags[1] & RF22_IPREAVAL) { // Serial.println("IPREAVAL"); _lastRssi = spiRead(RF22_REG_26_RSSI); clearRxBuf(); } }
// C++ level interrupt handler for this instance void RF22::handleInterrupt() { uint8_t _lastInterruptFlags[2]; // Read the interrupt flags which clears the interrupt spiBurstRead(RF22_REG_03_INTERRUPT_STATUS1, _lastInterruptFlags, 2); if (_lastInterruptFlags[0] & RF22_IFFERROR) { // cout << "RFM22 handleInterrupt(): IFFERROR\n"; resetFifos(); // Clears the interrupt if (_mode == RF22_MODE_TX) { restartTransmit(); } else if (_mode == RF22_MODE_RX) { clearRxBuf(); setModeIdle(); setModeRx(); } } // Caution, any delay here may cause a FF underflow or overflow if (_lastInterruptFlags[0] & RF22_ITXFFAEM) { // See if more data has to be loaded into the Tx FIFO sendNextFragment(); //cout << "RFM22 handleInterrupt(): ITXFFAEM\n"; } if (_lastInterruptFlags[0] & RF22_IRXFFAFULL) { // Caution, any delay here may cause a FF overflow // Read some data from the Rx FIFO readNextFragment(); cout << "RFM22 handleInterrupt(): IRXFFAFULL\n"; } if (_lastInterruptFlags[0] & RF22_IEXT) { // This is not enabled by the base code, but users may want to enable it handleExternalInterrupt(); cout << "RFM22 handleInterrupt(): IEXT\n"; } if (_lastInterruptFlags[1] & RF22_IWUT) { // This is not enabled by the base code, but users may want to enable it handleWakeupTimerInterrupt(); } if (_lastInterruptFlags[0] & RF22_IPKSENT) { _txGood++; // Transmission does not automatically clear the tx buffer. // Could retransmit if we wanted // RF22 transitions automatically to Idle _mode = RF22_MODE_IDLE; } if (_lastInterruptFlags[0] & RF22_IPKVALID) { // cout << "RFM22 handleInterrupt(): IPKVALID\n"; fflush(stdout); uint8_t len = spiRead(RF22_REG_4B_RECEIVED_PACKET_LENGTH); // May have already read one or more fragments // Get any remaining unread octets, based on the expected length // First make sure we dont overflow the buffer in the case of a stupid length // or partial bad receives if (len > RF22_MAX_MESSAGE_LEN || len < _bufLen) { _rxBad++; _mode = RF22_MODE_IDLE; clearRxBuf(); return; // Hmmm receiver buffer overflow. } spiBurstRead(RF22_REG_7F_FIFO_ACCESS, _buf, 64); resetRxFifo(); setModeIdle(); setModeRx(); // spiBurstRead(RF22_REG_7F_FIFO_ACCESS, _buf + _bufLen, len - _bufLen); _rxGood++; _bufLen = len; _mode = RF22_MODE_IDLE; _rxBufValid = true; //notify registered dispatcherModule dispatcher->receiveMessage(this); } if (_lastInterruptFlags[0] & RF22_ICRCERROR) { cout << "RFM22 handleInterrupt(): ICRCERR\n"; _rxBad++; clearRxBuf(); resetRxFifo(); _mode = RF22_MODE_IDLE; setModeRx(); // Keep trying } if (_lastInterruptFlags[1] & RF22_IPREAVAL) { // cout << "RFM22 handleInterrupt(): IPREAVAL\n"; _lastRssi = spiRead(RF22_REG_26_RSSI); // clearRxBuf(); } }