static inline bool writeFlowEventPacketFile(flowOutputState state, FlowEventPacket flow) { caerEventPacketHeader header = (caerEventPacketHeader) flow; if (caerEventPacketHeaderGetEventValid(header) == 0) { return (false); } for (int32_t i = 0; i < caerEventPacketHeaderGetEventNumber(header); i++) { FlowEvent e = &(flow->events[i]); if (e == NULL) { caerLog(CAER_LOG_ERROR,SUBSYSTEM_FILE,"Event null pointer found."); return (false); } if (!e->hasFlow) {continue;} // Get event data uint8_t x = (uint8_t) caerPolarityEventGetX((caerPolarityEvent) e); uint8_t y = (uint8_t) caerPolarityEventGetY((caerPolarityEvent) e); int32_t t = caerPolarityEventGetTimestamp((caerPolarityEvent) e); bool p = caerPolarityEventGetPolarity((caerPolarityEvent) e); double u = e->u; double v = e->v; // Write to file if (state->fileLineNumber < FILE_MAX_NUMBER_OF_LINES) { fprintf(state->file,"%3i,%3i,%10i,%d,%4.3f,%4.3f\n",x,y,t,p,u,v); state->fileLineNumber++; } else { // If too many lines, stop logging to prevent overrun if (state->fileLineNumber == FILE_MAX_NUMBER_OF_LINES) { caerLog(CAER_LOG_NOTICE, SUBSYSTEM_FILE, "File log reached limit of %d lines - " "no more lines will be added.", FILE_MAX_NUMBER_OF_LINES); state->fileLineNumber++; } } } return (true); }
static inline bool sendFlowEventPacketUart(FlowEventPacket flow) { caerEventPacketHeader header = (caerEventPacketHeader) flow; uint32_t packetSize = (uint32_t) caerEventPacketHeaderGetEventNumber(header); if (packetSize == 0) { // No events to send - return return (false); } // Events are separated by unsigned ints of value 255. This value should // never occur as pixel location unsigned char eventSeparator = 255; // Iterate through packet and send events for (uint32_t i = 0; i < packetSize; i++) { FlowEvent e = &(flow->events[i]); if (e == NULL) { caerLog(CAER_LOG_ERROR,SUBSYSTEM_UART,"Event null pointer found."); return (false); } if (!e->hasFlow) {continue;} uint8_t x = (uint8_t) caerPolarityEventGetX((caerPolarityEvent) e); uint8_t y = (uint8_t) caerPolarityEventGetY((caerPolarityEvent) e); int32_t t = caerPolarityEventGetTimestamp((caerPolarityEvent) e); int16_t u = (int16_t) (e->u*100); int16_t v = (int16_t) (e->v*100); // Send data over UART if (uart_tx(sizeof(x),(unsigned char*) &x) || uart_tx(sizeof(y),(unsigned char*) &y) || uart_tx(sizeof(t),(unsigned char*) &t) || uart_tx(sizeof(u),(unsigned char*) &u) || uart_tx(sizeof(v),(unsigned char*) &v) || uart_tx(sizeof(eventSeparator), &eventSeparator)) { caerLog(CAER_LOG_ERROR,SUBSYSTEM_UART,"Event info not fully sent."); return (false); } } return (true); }
int main(void) { // Install signal handler for global shutdown. #if defined(_WIN32) if (signal(SIGTERM, &globalShutdownSignalHandler) == SIG_ERR) { caerLog(CAER_LOG_CRITICAL, "ShutdownAction", "Failed to set signal handler for SIGTERM. Error: %d.", errno); return (EXIT_FAILURE); } if (signal(SIGINT, &globalShutdownSignalHandler) == SIG_ERR) { caerLog(CAER_LOG_CRITICAL, "ShutdownAction", "Failed to set signal handler for SIGINT. Error: %d.", errno); return (EXIT_FAILURE); } #else struct sigaction shutdownAction; shutdownAction.sa_handler = &globalShutdownSignalHandler; shutdownAction.sa_flags = 0; sigemptyset(&shutdownAction.sa_mask); sigaddset(&shutdownAction.sa_mask, SIGTERM); sigaddset(&shutdownAction.sa_mask, SIGINT); if (sigaction(SIGTERM, &shutdownAction, NULL) == -1) { caerLog(CAER_LOG_CRITICAL, "ShutdownAction", "Failed to set signal handler for SIGTERM. Error: %d.", errno); return (EXIT_FAILURE); } if (sigaction(SIGINT, &shutdownAction, NULL) == -1) { caerLog(CAER_LOG_CRITICAL, "ShutdownAction", "Failed to set signal handler for SIGINT. Error: %d.", errno); return (EXIT_FAILURE); } #endif // Open a DVS128, give it a device ID of 1, and don't care about USB bus or SN restrictions. caerDeviceHandle dvs128_handle = caerDeviceOpen(1, CAER_DEVICE_DVS128, 0, 0, NULL); if (dvs128_handle == NULL) { return (EXIT_FAILURE); } // Let's take a look at the information we have on the device. struct caer_dvs128_info dvs128_info = caerDVS128InfoGet(dvs128_handle); printf("%s --- ID: %d, Master: %d, DVS X: %d, DVS Y: %d, Logic: %d.\n", dvs128_info.deviceString, dvs128_info.deviceID, dvs128_info.deviceIsMaster, dvs128_info.dvsSizeX, dvs128_info.dvsSizeY, dvs128_info.logicVersion); // Send the default configuration before using the device. // No configuration is sent automatically! caerDeviceSendDefaultConfig(dvs128_handle); // Tweak some biases, to increase bandwidth in this case. caerDeviceConfigSet(dvs128_handle, DVS128_CONFIG_BIAS, DVS128_CONFIG_BIAS_PR, 695); caerDeviceConfigSet(dvs128_handle, DVS128_CONFIG_BIAS, DVS128_CONFIG_BIAS_FOLL, 867); // Let's verify they really changed! uint32_t prBias, follBias; caerDeviceConfigGet(dvs128_handle, DVS128_CONFIG_BIAS, DVS128_CONFIG_BIAS_PR, &prBias); caerDeviceConfigGet(dvs128_handle, DVS128_CONFIG_BIAS, DVS128_CONFIG_BIAS_FOLL, &follBias); printf("New bias values --- PR: %d, FOLL: %d.\n", prBias, follBias); // Now let's get start getting some data from the device. We just loop in blocking mode, // no notification needed regarding new events. The shutdown notification, for example if // the device is disconnected, should be listened to. caerDeviceDataStart(dvs128_handle, NULL, NULL, NULL, &usbShutdownHandler, NULL); // Let's turn on blocking data-get mode to avoid wasting resources. caerDeviceConfigSet(dvs128_handle, CAER_HOST_CONFIG_DATAEXCHANGE, CAER_HOST_CONFIG_DATAEXCHANGE_BLOCKING, true); while (!atomic_load_explicit(&globalShutdown, memory_order_relaxed)) { caerEventPacketContainer packetContainer = caerDeviceDataGet(dvs128_handle); if (packetContainer == NULL) { continue; // Skip if nothing there. } int32_t packetNum = caerEventPacketContainerGetEventPacketsNumber(packetContainer); printf("\nGot event container with %d packets (allocated).\n", packetNum); for (int32_t i = 0; i < packetNum; i++) { caerEventPacketHeader packetHeader = caerEventPacketContainerGetEventPacket(packetContainer, i); if (packetHeader == NULL) { printf("Packet %d is empty (not present).\n", i); continue; // Skip if nothing there. } printf("Packet %d of type %d -> size is %d.\n", i, caerEventPacketHeaderGetEventType(packetHeader), caerEventPacketHeaderGetEventNumber(packetHeader)); // Packet 0 is always the special events packet for DVS128, while packet is the polarity events packet. if (i == POLARITY_EVENT) { caerPolarityEventPacket polarity = (caerPolarityEventPacket) packetHeader; // Get full timestamp and addresses of first event. caerPolarityEvent firstEvent = caerPolarityEventPacketGetEvent(polarity, 0); int32_t ts = caerPolarityEventGetTimestamp(firstEvent); uint16_t x = caerPolarityEventGetX(firstEvent); uint16_t y = caerPolarityEventGetY(firstEvent); bool pol = caerPolarityEventGetPolarity(firstEvent); printf("First polarity event - ts: %d, x: %d, y: %d, pol: %d.\n", ts, x, y, pol); } } caerEventPacketContainerFree(packetContainer); } caerDeviceDataStop(dvs128_handle); caerDeviceClose(&dvs128_handle); printf("Shutdown successful.\n"); return (EXIT_SUCCESS); }