jerrym | f157933 | 2013-02-07 01:56:28 +0000 | [diff] [blame] | 1 | /*----------------------------------------------------------------------------*/
|
| 2 | /* Copyright (c) FIRST 2008. All Rights Reserved. */
|
| 3 | /* Open Source Software - may be modified and shared by FRC teams. The code */
|
| 4 | /* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
|
| 5 | /*----------------------------------------------------------------------------*/
|
| 6 |
|
| 7 | #include "DriverStationLCD.h"
|
| 8 | #include "NetworkCommunication/FRCComm.h"
|
| 9 | #include "NetworkCommunication/UsageReporting.h"
|
| 10 | #include "Synchronized.h"
|
| 11 | #include "WPIErrors.h"
|
| 12 | #include <strLib.h>
|
| 13 |
|
| 14 | const UINT32 DriverStationLCD::kSyncTimeout_ms;
|
| 15 | const UINT16 DriverStationLCD::kFullDisplayTextCommand;
|
| 16 | const INT32 DriverStationLCD::kLineLength;
|
| 17 | const INT32 DriverStationLCD::kNumLines;
|
| 18 | DriverStationLCD* DriverStationLCD::m_instance = NULL;
|
| 19 |
|
| 20 | /**
|
| 21 | * DriverStationLCD contructor.
|
| 22 | *
|
| 23 | * This is only called once the first time GetInstance() is called
|
| 24 | */
|
| 25 | DriverStationLCD::DriverStationLCD()
|
| 26 | : m_textBuffer (NULL)
|
| 27 | , m_textBufferSemaphore (NULL)
|
| 28 | {
|
| 29 | m_textBuffer = new char[USER_DS_LCD_DATA_SIZE];
|
| 30 | memset(m_textBuffer, ' ', USER_DS_LCD_DATA_SIZE);
|
| 31 |
|
| 32 | *((UINT16 *)m_textBuffer) = kFullDisplayTextCommand;
|
| 33 |
|
| 34 | m_textBufferSemaphore = semMCreate(SEM_DELETE_SAFE);
|
| 35 |
|
| 36 | nUsageReporting::report(nUsageReporting::kResourceType_DriverStationLCD, 0);
|
| 37 |
|
| 38 | AddToSingletonList();
|
| 39 | }
|
| 40 |
|
| 41 | DriverStationLCD::~DriverStationLCD()
|
| 42 | {
|
| 43 | semDelete(m_textBufferSemaphore);
|
| 44 | delete [] m_textBuffer;
|
| 45 | m_instance = NULL;
|
| 46 | }
|
| 47 |
|
| 48 | /**
|
| 49 | * Return a pointer to the singleton DriverStationLCD.
|
| 50 | */
|
| 51 | DriverStationLCD* DriverStationLCD::GetInstance()
|
| 52 | {
|
| 53 | if (m_instance == NULL)
|
| 54 | {
|
| 55 | m_instance = new DriverStationLCD();
|
| 56 | }
|
| 57 | return m_instance;
|
| 58 | }
|
| 59 |
|
| 60 | /**
|
| 61 | * Send the text data to the Driver Station.
|
| 62 | */
|
| 63 | void DriverStationLCD::UpdateLCD()
|
| 64 | {
|
| 65 | Synchronized sync(m_textBufferSemaphore);
|
| 66 | setUserDsLcdData(m_textBuffer, USER_DS_LCD_DATA_SIZE, kSyncTimeout_ms);
|
| 67 | }
|
| 68 |
|
| 69 | /**
|
| 70 | * Print formatted text to the Driver Station LCD text bufer.
|
| 71 | *
|
| 72 | * Use UpdateLCD() periodically to actually send the text to the Driver Station.
|
| 73 | *
|
| 74 | * @param line The line on the LCD to print to.
|
| 75 | * @param startingColumn The column to start printing to. This is a 1-based number.
|
| 76 | * @param writeFmt The printf format string describing how to print.
|
| 77 | */
|
| 78 | void DriverStationLCD::Printf(Line line, INT32 startingColumn, const char *writeFmt, ...)
|
| 79 | {
|
| 80 | va_list args;
|
| 81 | va_start (args, writeFmt);
|
| 82 | VPrintf(line, startingColumn, writeFmt, args);
|
| 83 | va_end (args);
|
| 84 | }
|
| 85 |
|
| 86 | void DriverStationLCD::VPrintf(Line line, INT32 startingColumn, const char *writeFmt, va_list args)
|
| 87 | {
|
| 88 | UINT32 start = startingColumn - 1;
|
| 89 | INT32 maxLength = kLineLength - start;
|
| 90 | char lineBuffer[kLineLength + 1];
|
| 91 |
|
| 92 | if (startingColumn < 1 || startingColumn > kLineLength)
|
| 93 | {
|
| 94 | wpi_setWPIErrorWithContext(ParameterOutOfRange, "startingColumn");
|
| 95 | return;
|
| 96 | }
|
| 97 |
|
| 98 | if (line < kMain_Line6 || line > kUser_Line6)
|
| 99 | {
|
| 100 | wpi_setWPIErrorWithContext(ParameterOutOfRange, "line");
|
| 101 | return;
|
| 102 | }
|
| 103 |
|
| 104 | {
|
| 105 | Synchronized sync(m_textBufferSemaphore);
|
| 106 | // snprintf appends NULL to its output. Therefore we can't write directly to the buffer.
|
| 107 | INT32 length = vsnprintf(lineBuffer, kLineLength + 1, writeFmt, args);
|
| 108 | if (length < 0) length = kLineLength;
|
| 109 |
|
| 110 | memcpy(m_textBuffer + start + line * kLineLength + sizeof(UINT16), lineBuffer, std::min(maxLength,length));
|
| 111 | }
|
| 112 | }
|
| 113 |
|
| 114 | /**
|
| 115 | * Print formatted text to the Driver Station LCD text bufer. This function
|
| 116 | * pads the line with empty spaces.
|
| 117 | *
|
| 118 | * Use UpdateLCD() periodically to actually send the text to the Driver Station.
|
| 119 | *
|
| 120 | * @param line The line on the LCD to print to.
|
| 121 | * @param writeFmt The printf format string describing how to print.
|
| 122 | */
|
| 123 | void DriverStationLCD::PrintfLine(Line line, const char *writeFmt, ...)
|
| 124 | {
|
| 125 | va_list args;
|
| 126 | va_start (args, writeFmt);
|
| 127 | VPrintfLine(line, writeFmt, args);
|
| 128 | va_end (args);
|
| 129 | }
|
| 130 |
|
| 131 | void DriverStationLCD::VPrintfLine(Line line, const char *writeFmt, va_list args)
|
| 132 | {
|
| 133 | char lineBuffer[kLineLength + 1];
|
| 134 |
|
| 135 | if (line < kMain_Line6 || line > kUser_Line6)
|
| 136 | {
|
| 137 | wpi_setWPIErrorWithContext(ParameterOutOfRange, "line");
|
| 138 | return;
|
| 139 | }
|
| 140 |
|
| 141 | {
|
| 142 | Synchronized sync(m_textBufferSemaphore);
|
| 143 | // snprintf appends NULL to its output. Therefore we can't write directly to the buffer.
|
| 144 | INT32 length = std::min(vsnprintf(lineBuffer, kLineLength + 1, writeFmt, args), kLineLength);
|
| 145 | if (length < 0) length = kLineLength;
|
| 146 |
|
| 147 | // Fill the rest of the buffer
|
| 148 | if (length < kLineLength)
|
| 149 | {
|
| 150 | memset(lineBuffer + length, ' ', kLineLength - length);
|
| 151 | }
|
| 152 |
|
| 153 | memcpy(m_textBuffer + line * kLineLength + sizeof(UINT16), lineBuffer, kLineLength);
|
| 154 | }
|
| 155 | }
|
| 156 |
|
| 157 | /**
|
| 158 | * Clear all lines on the LCD.
|
| 159 | */
|
| 160 | void DriverStationLCD::Clear()
|
| 161 | {
|
| 162 | Synchronized sync(m_textBufferSemaphore);
|
| 163 | memset(m_textBuffer + sizeof(UINT16), ' ', kLineLength*kNumLines);
|
| 164 | }
|
| 165 |
|