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 public int update(int dmaHandle, double timeoutSeconds) { 030 m_timeStamp = DMAJNI.readDMA(dmaHandle, timeoutSeconds, m_dataBuffer, m_storage); 031 return m_storage[25]; 032 } 033 034 public int getCaptureSize() { 035 return m_storage[22]; 036 } 037 038 public int getTriggerChannels() { 039 return m_storage[23]; 040 } 041 042 public int getRemaining() { 043 return m_storage[24]; 044 } 045 046 public long getTime() { 047 return m_timeStamp; 048 } 049 050 private BaseStore addSensorInternal(int handle) { 051 BaseStore sensorData = DMAJNI.getSensorReadData(handle); 052 m_propertyMap.put(handle, sensorData); 053 return sensorData; 054 } 055 056 public void addSensor(int handle) { 057 addSensorInternal(handle); 058 } 059 060 private int readValue(int valueType, int index) { 061 int offset = m_storage[valueType]; 062 if (offset == -1) { 063 throw new RuntimeException("Resource not found in DMA capture"); 064 } 065 return m_dataBuffer[offset + index]; 066 } 067 068 public int getEncoder(int encoderHandle) { 069 BaseStore data = m_propertyMap.get(encoderHandle); 070 if (data == null) { 071 data = addSensorInternal(encoderHandle); 072 } 073 return readValue(data.m_valueType, data.m_index); 074 } 075 076 public int getEncoderPeriod(int encoderHandle) { 077 BaseStore data = m_propertyMap.get(encoderHandle); 078 if (data == null) { 079 data = addSensorInternal(encoderHandle); 080 } 081 // + 2 Hack, but needed to not have to call into JNI 082 return readValue(data.m_valueType + 2, data.m_index); 083 } 084 085 public int getCounter(int counterHandle) { 086 BaseStore data = m_propertyMap.get(counterHandle); 087 if (data == null) { 088 data = addSensorInternal(counterHandle); 089 } 090 return readValue(data.m_valueType, data.m_index); 091 } 092 093 public int getCounterPeriod(int counterHandle) { 094 BaseStore data = m_propertyMap.get(counterHandle); 095 if (data == null) { 096 data = addSensorInternal(counterHandle); 097 } 098 // Hack, but needed to not have to call into JNI 099 return readValue(data.m_valueType + 2, data.m_index); 100 } 101 102 public boolean getDigitalSource(int digitalSourceHandle) { 103 BaseStore data = m_propertyMap.get(digitalSourceHandle); 104 if (data == null) { 105 data = addSensorInternal(digitalSourceHandle); 106 } 107 108 int value = readValue(data.m_valueType, 0); 109 110 return ((value >> data.m_index) & 0x1) != 0; 111 } 112 113 public int getAnalogInput(int analogInputHandle) { 114 BaseStore data = m_propertyMap.get(analogInputHandle); 115 if (data == null) { 116 data = addSensorInternal(analogInputHandle); 117 } 118 119 int value = readValue(data.m_valueType, data.m_index / 2); 120 if ((data.m_index % 2) != 0) { 121 return (value >>> 16) & 0xFFFF; 122 } else { 123 return value & 0xFFFF; 124 } 125 } 126 127 public int getAnalogInputAveraged(int analogInputHandle) { 128 BaseStore data = m_propertyMap.get(analogInputHandle); 129 if (data == null) { 130 data = addSensorInternal(analogInputHandle); 131 } 132 133 // + 2 Hack, but needed to not have to call into JNI 134 int value = readValue(data.m_valueType + 2, data.m_index); 135 return value; 136 } 137 138 public void getAnalogAccumulator(int analogInputHandle, AccumulatorResult result) { 139 BaseStore data = m_propertyMap.get(analogInputHandle); 140 if (data == null) { 141 data = addSensorInternal(analogInputHandle); 142 } 143 144 if (data.m_index == 0) { 145 int val0 = readValue(kEnable_Accumulator0, 0); 146 int val1 = readValue(kEnable_Accumulator0, 1); 147 int val2 = readValue(kEnable_Accumulator0, 2); 148 result.count = val2; 149 result.value = ((long) val1 << 32) | val0; 150 } else if (data.m_index == 1) { 151 int val0 = readValue(kEnable_Accumulator1, 0); 152 int val1 = readValue(kEnable_Accumulator1, 1); 153 int val2 = readValue(kEnable_Accumulator1, 2); 154 result.count = val2; 155 result.value = ((long) val1 << 32) | val0; 156 } else { 157 throw new RuntimeException("Resource not found in DMA capture"); 158 } 159 } 160 161 public int getDutyCycleOutput(int dutyCycleHandle) { 162 BaseStore data = m_propertyMap.get(dutyCycleHandle); 163 if (data == null) { 164 data = addSensorInternal(dutyCycleHandle); 165 } 166 return readValue(data.m_valueType, data.m_index); 167 } 168}