001// Copyright (c) FIRST and other WPILib contributors. 002// Open Source Software; you can modify and/or share it under the terms of 003// the WPILib BSD license file in the root directory of this project. 004 005package edu.wpi.first.hal; 006 007import java.util.HashMap; 008import java.util.Map; 009 010public class DMAJNISample { 011 private static final int kEnable_Accumulator0 = 8; 012 private static final int kEnable_Accumulator1 = 9; 013 014 static class BaseStore { 015 public final int m_valueType; 016 public final int m_index; 017 018 BaseStore(int valueType, int index) { 019 this.m_valueType = valueType; 020 this.m_index = index; 021 } 022 } 023 024 private final int[] m_dataBuffer = new int[100]; 025 private final int[] m_storage = new int[100]; 026 private long m_timeStamp; 027 private Map<Integer, BaseStore> m_propertyMap = new HashMap<>(); 028 029 /** Default constructor. */ 030 public DMAJNISample() {} 031 032 public int update(int dmaHandle, double timeoutSeconds) { 033 m_timeStamp = DMAJNI.readDMA(dmaHandle, timeoutSeconds, m_dataBuffer, m_storage); 034 return m_storage[25]; 035 } 036 037 public int getCaptureSize() { 038 return m_storage[22]; 039 } 040 041 public int getTriggerChannels() { 042 return m_storage[23]; 043 } 044 045 public int getRemaining() { 046 return m_storage[24]; 047 } 048 049 public long getTime() { 050 return m_timeStamp; 051 } 052 053 private BaseStore addSensorInternal(int handle) { 054 BaseStore sensorData = DMAJNI.getSensorReadData(handle); 055 m_propertyMap.put(handle, sensorData); 056 return sensorData; 057 } 058 059 public void addSensor(int handle) { 060 addSensorInternal(handle); 061 } 062 063 private int readValue(int valueType, int index) { 064 int offset = m_storage[valueType]; 065 if (offset == -1) { 066 throw new RuntimeException("Resource not found in DMA capture"); 067 } 068 return m_dataBuffer[offset + index]; 069 } 070 071 public int getEncoder(int encoderHandle) { 072 BaseStore data = m_propertyMap.get(encoderHandle); 073 if (data == null) { 074 data = addSensorInternal(encoderHandle); 075 } 076 return readValue(data.m_valueType, data.m_index); 077 } 078 079 public int getEncoderPeriod(int encoderHandle) { 080 BaseStore data = m_propertyMap.get(encoderHandle); 081 if (data == null) { 082 data = addSensorInternal(encoderHandle); 083 } 084 // + 2 Hack, but needed to not have to call into JNI 085 return readValue(data.m_valueType + 2, data.m_index); 086 } 087 088 public int getCounter(int counterHandle) { 089 BaseStore data = m_propertyMap.get(counterHandle); 090 if (data == null) { 091 data = addSensorInternal(counterHandle); 092 } 093 return readValue(data.m_valueType, data.m_index); 094 } 095 096 public int getCounterPeriod(int counterHandle) { 097 BaseStore data = m_propertyMap.get(counterHandle); 098 if (data == null) { 099 data = addSensorInternal(counterHandle); 100 } 101 // Hack, but needed to not have to call into JNI 102 return readValue(data.m_valueType + 2, data.m_index); 103 } 104 105 public boolean getDigitalSource(int digitalSourceHandle) { 106 BaseStore data = m_propertyMap.get(digitalSourceHandle); 107 if (data == null) { 108 data = addSensorInternal(digitalSourceHandle); 109 } 110 111 int value = readValue(data.m_valueType, 0); 112 113 return ((value >> data.m_index) & 0x1) != 0; 114 } 115 116 public int getAnalogInput(int analogInputHandle) { 117 BaseStore data = m_propertyMap.get(analogInputHandle); 118 if (data == null) { 119 data = addSensorInternal(analogInputHandle); 120 } 121 122 int value = readValue(data.m_valueType, data.m_index / 2); 123 if ((data.m_index % 2) != 0) { 124 return (value >>> 16) & 0xFFFF; 125 } else { 126 return value & 0xFFFF; 127 } 128 } 129 130 public int getAnalogInputAveraged(int analogInputHandle) { 131 BaseStore data = m_propertyMap.get(analogInputHandle); 132 if (data == null) { 133 data = addSensorInternal(analogInputHandle); 134 } 135 136 // + 2 Hack, but needed to not have to call into JNI 137 return readValue(data.m_valueType + 2, data.m_index); 138 } 139 140 public void getAnalogAccumulator(int analogInputHandle, AccumulatorResult result) { 141 BaseStore data = m_propertyMap.get(analogInputHandle); 142 if (data == null) { 143 data = addSensorInternal(analogInputHandle); 144 } 145 146 if (data.m_index == 0) { 147 int val0 = readValue(kEnable_Accumulator0, 0); 148 int val1 = readValue(kEnable_Accumulator0, 1); 149 int val2 = readValue(kEnable_Accumulator0, 2); 150 result.count = val2; 151 result.value = ((long) val1 << 32) | val0; 152 } else if (data.m_index == 1) { 153 int val0 = readValue(kEnable_Accumulator1, 0); 154 int val1 = readValue(kEnable_Accumulator1, 1); 155 int val2 = readValue(kEnable_Accumulator1, 2); 156 result.count = val2; 157 result.value = ((long) val1 << 32) | val0; 158 } else { 159 throw new RuntimeException("Resource not found in DMA capture"); 160 } 161 } 162 163 public int getDutyCycleOutput(int dutyCycleHandle) { 164 BaseStore data = m_propertyMap.get(dutyCycleHandle); 165 if (data == null) { 166 data = addSensorInternal(dutyCycleHandle); 167 } 168 return readValue(data.m_valueType, data.m_index); 169 } 170}