001/*----------------------------------------------------------------------------*/ 002/* Copyright (c) FIRST 2014. All Rights Reserved. */ 003/* Open Source Software - may be modified and shared by FRC teams. The code */ 004/* must be accompanied by the FIRST BSD license file in the root directory of */ 005/* the project. */ 006/*----------------------------------------------------------------------------*/ 007package edu.wpi.first.wpilibj; 008 009import java.nio.ByteOrder; 010import java.nio.IntBuffer; 011import java.nio.LongBuffer; 012import java.nio.ByteBuffer; 013 014//import com.sun.jna.Pointer; 015 016 017import edu.wpi.first.wpilibj.communication.FRCNetworkCommunicationsLibrary.tResourceType; 018import edu.wpi.first.wpilibj.communication.UsageReporting; 019import edu.wpi.first.wpilibj.hal.AnalogJNI; 020import edu.wpi.first.wpilibj.hal.HALUtil; 021import edu.wpi.first.wpilibj.livewindow.LiveWindow; 022import edu.wpi.first.wpilibj.livewindow.LiveWindowSendable; 023import edu.wpi.first.wpilibj.tables.ITable; 024import edu.wpi.first.wpilibj.util.AllocationException; 025import edu.wpi.first.wpilibj.util.CheckedAllocationException; 026 027/** 028 * Analog output class. 029 */ 030public class AnalogOutput extends SensorBase implements LiveWindowSendable { 031 private static Resource channels = new Resource(kAnalogOutputChannels); 032 private ByteBuffer m_port; 033 private int m_channel; 034 035 /** 036 * Construct an analog output on a specified MXP channel. 037 * 038 * @param channel 039 * The channel number to represent. 040 */ 041 public AnalogOutput(final int channel) { 042 m_channel = channel; 043 044 if (AnalogJNI.checkAnalogOutputChannel(channel) == 0) { 045 throw new AllocationException("Analog output channel " + m_channel 046 + " cannot be allocated. Channel is not present."); 047 } 048 try { 049 channels.allocate(channel); 050 } catch (CheckedAllocationException e) { 051 throw new AllocationException("Analog output channel " + m_channel 052 + " is already allocated"); 053 } 054 055 ByteBuffer port_pointer = AnalogJNI.getPort((byte)channel); 056 ByteBuffer status = ByteBuffer.allocateDirect(4); 057 // set the byte order 058 status.order(ByteOrder.LITTLE_ENDIAN); 059 m_port = AnalogJNI.initializeAnalogOutputPort(port_pointer, status.asIntBuffer()); 060 HALUtil.checkStatus(status.asIntBuffer()); 061 062 LiveWindow.addSensor("AnalogOutput", channel, this); 063 UsageReporting.report(tResourceType.kResourceType_AnalogChannel, channel, 1); 064 } 065 066 /** 067 * Channel destructor. 068 */ 069 public void free() { 070 channels.free(m_channel); 071 m_channel = 0; 072 } 073 074 public void setVoltage(double voltage) { 075 ByteBuffer status = ByteBuffer.allocateDirect(4); 076 status.order(ByteOrder.LITTLE_ENDIAN); 077 078 AnalogJNI.setAnalogOutput(m_port, voltage, status.asIntBuffer()); 079 080 HALUtil.checkStatus(status.asIntBuffer()); 081 } 082 083 public double getVoltage() { 084 ByteBuffer status = ByteBuffer.allocateDirect(4); 085 status.order(ByteOrder.LITTLE_ENDIAN); 086 087 double voltage = AnalogJNI.getAnalogOutput(m_port, status.asIntBuffer()); 088 089 HALUtil.checkStatus(status.asIntBuffer()); 090 091 return voltage; 092 } 093 094 /* 095 * Live Window code, only does anything if live window is activated. 096 */ 097 public String getSmartDashboardType() { 098 return "Analog Output"; 099 } 100 101 private ITable m_table; 102 103 /** 104 * {@inheritDoc} 105 */ 106 public void initTable(ITable subtable) { 107 m_table = subtable; 108 updateTable(); 109 } 110 111 /** 112 * {@inheritDoc} 113 */ 114 public void updateTable() { 115 if (m_table != null) { 116 m_table.putNumber("Value", getVoltage()); 117 } 118 } 119 120 /** 121 * {@inheritDoc} 122 */ 123 public ITable getTable() { 124 return m_table; 125 } 126 127 /** 128 * Analog Channels don't have to do anything special when entering the 129 * LiveWindow. {@inheritDoc} 130 */ 131 public void startLiveWindowMode() { 132 } 133 134 /** 135 * Analog Channels don't have to do anything special when exiting the 136 * LiveWindow. {@inheritDoc} 137 */ 138 public void stopLiveWindowMode() { 139 } 140}