001 /*----------------------------------------------------------------------------*/
002 /* Copyright (c) FIRST 2008-2012. 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 /*----------------------------------------------------------------------------*/
007
008 package edu.wpi.first.wpilibj;
009
010 import edu.wpi.first.wpilibj.communication.FRCControl;
011 import edu.wpi.first.wpilibj.communication.UsageReporting;
012 import edu.wpi.first.wpilibj.parsing.IInputOutput;
013
014 /**
015 * Provide access to "LCD" on the Driver Station.
016 * This is the Messages box on the DS Operation tab.
017 *
018 * Buffer the printed data locally and then send it
019 * when UpdateLCD is called.
020 */
021 public class DriverStationLCD extends SensorBase implements IInputOutput{
022
023 private static DriverStationLCD m_instance;
024 /**
025 * Driver station timeout in milliseconds
026 */
027 public static final int kSyncTimeout_ms = 20;
028 /**
029 * Command to display text
030 */
031 public static final int kFullDisplayTextCommand = 0x9FFF;
032 /**
033 * Maximum line length for Driver Station display
034 */
035 public static final int kLineLength = 21;
036 /**
037 * Total number of lines available
038 */
039 public static final int kNumLines = 6;
040
041 /**
042 * The line number on the Driver Station LCD
043 */
044 public static class Line {
045
046 /**
047 * The integer value representing this enumeration
048 */
049 public final int value;
050 static final int kMain6_val = 0;
051 static final int kUser1_val = 0;
052 static final int kUser2_val = 1;
053 static final int kUser3_val = 2;
054 static final int kUser4_val = 3;
055 static final int kUser5_val = 4;
056 static final int kUser6_val = 5;
057 /**
058 * @deprecated Use kUser1
059 * Line at the Top of the screen
060 */
061 public static final Line kMain6 = new Line(kMain6_val);
062 /**
063 * Line at the Top of the screen
064 */
065 public static final Line kUser1 = new Line(kUser1_val);
066 /**
067 * Line on the user screen
068 */
069 public static final Line kUser2 = new Line(kUser2_val);
070 /**
071 * Line on the user screen
072 */
073 public static final Line kUser3 = new Line(kUser3_val);
074 /**
075 * Line on the user screen
076 */
077 public static final Line kUser4 = new Line(kUser4_val);
078 /**
079 * Line on the user screen
080 */
081 public static final Line kUser5 = new Line(kUser5_val);
082 /**
083 * Bottom line on the user screen
084 */
085 public static final Line kUser6 = new Line(kUser6_val);
086
087 private Line(int value) {
088 this.value = value;
089 }
090 }
091
092 byte[] m_textBuffer;
093
094 /**
095 * Get an instance of the DriverStationLCD
096 * @return an instance of the DriverStationLCD
097 */
098 public static synchronized DriverStationLCD getInstance() {
099 if (m_instance == null)
100 m_instance = new DriverStationLCD();
101 return m_instance;
102 }
103
104 /**
105 * DriverStationLCD constructor.
106 *
107 * This is only called once the first time GetInstance() is called
108 */
109 private DriverStationLCD() {
110 m_textBuffer = new byte[FRCControl.USER_DS_LCD_DATA_SIZE];
111
112 for (int i = 0; i < FRCControl.USER_DS_LCD_DATA_SIZE; i++) {
113 m_textBuffer[i] = ' ';
114 }
115
116 m_textBuffer[0] = (byte) (kFullDisplayTextCommand >> 8);
117 m_textBuffer[1] = (byte) kFullDisplayTextCommand;
118
119 UsageReporting.report(UsageReporting.kResourceType_DriverStationLCD, 0);
120 }
121
122 /**
123 * Send the text data to the Driver Station.
124 */
125 public synchronized void updateLCD() {
126 FRCControl.setUserDsLcdData(m_textBuffer, FRCControl.USER_DS_LCD_DATA_SIZE, kSyncTimeout_ms);
127 }
128
129 /**
130 * Print formatted text to the Driver Station LCD text buffer.
131 *
132 * Use UpdateLCD() periodically to actually send the test to the Driver Station.
133 *
134 * @param line The line on the LCD to print to.
135 * @param startingColumn The column to start printing to. This is a 1-based number.
136 * @param text the text to print
137 */
138 public void println(Line line, int startingColumn, String text) {
139 int start = startingColumn - 1;
140 int maxLength = kLineLength - start;
141
142 if (startingColumn < 1 || startingColumn > kLineLength) {
143 throw new IndexOutOfBoundsException("Column must be between 1 and " + kLineLength + ", inclusive");
144 }
145
146 int length = text.length();
147 int finalLength = (length < maxLength ? length : maxLength);
148 synchronized (this) {
149 for (int i = 0; i < finalLength; i++) {
150 m_textBuffer[i + start + line.value * kLineLength + 2] = (byte)text.charAt(i);
151 }
152 }
153 }
154
155 /**
156 * Print formatted text to the Driver Station LCD text buffer.
157 *
158 * Use UpdateLCD() periodically to actually send the test to the Driver Station.
159 *
160 * @param line The line on the LCD to print to.
161 * @param startingColumn The column to start printing to. This is a 1-based number.
162 * @param text the text to print
163 */
164 public void println(Line line, int startingColumn, StringBuffer text) {
165 int start = startingColumn - 1;
166 int maxLength = kLineLength - start;
167
168 if (startingColumn < 1 || startingColumn > kLineLength) {
169 throw new IndexOutOfBoundsException("Column must be between 1 and " + kLineLength + ", inclusive");
170 }
171
172 int length = text.length();
173 int finalLength = (length < maxLength ? length : maxLength);
174 synchronized (this) {
175 for (int i = 0; i < finalLength; i++) {
176 m_textBuffer[i + start + line.value * kLineLength + 2] = (byte) text.charAt(i);
177 }
178 }
179 }
180
181 /**
182 * Clear User Messages box on DS Operations Tab
183 *
184 * This method will clear all text currently displayed in the message box
185 */
186 public void clear() {
187 synchronized (this) {
188 for (int i=0; i < kLineLength*kNumLines; i++) {
189 m_textBuffer[i+2] = ' ';
190 }
191 }
192 updateLCD();
193 }
194 }