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