// Display (Crystalfontz CFA-635 USB LCD) // // Douglas Thrift // // $Id$ #ifndef _Display_hpp_ #define _Display_hpp_ #include #include #include class Display { int ucom; Pthreads::ThreadMutex ucomLock; Pthreads::ThreadCondition ucomCondition; volatile bool running; struct Packet { enum Command { PingCommand = 0x00, GetHardwareAndFirmwareVersion = 0x01, WriteUserFlashArea = 0x02, ReadUserFlashArea = 0x03, StoreCurrentStateAsBootState = 0x04, RebootResetHostOrPowerOffHost = 0x05, ClearLCDScreen = 0x06, SetLCDSpecialCharacterData = 0x09, Read8ByesOfLCDMemory = 0x0a, SetLCDCursorPosition = 0x0b, SetLCDCursorStyle = 0x0c, SetLCDContrast = 0x0d, SetLCDAndKeypadBacklight = 0x0e, SetUpFanReporting = 0x10, SetFanPower = 0x11, ReadDOWDeviceInformation = 0x12, SetUpTemperatureReporting = 0x13, ArbitraryDOWTransaction = 0x14, SendCommandDirectlyToTheLCDController = 0x16, ConfigureKeyReporting = 0x17, ReadKeypad = 0x18, SetFanPowerFailSafe = 0x19, SetFanTachometerGlitchFilter = 0x1a, QueryFanPowerAndFailSafeMask = 0x1b, SetATXPowerSwitchFunctionality = 0x1c, EnableDisableAndResetTheWatchdog = 0x1d, ReadReportingAndStatus = 0x1e, SendDataToLCD = 0x1f, SetBaudRate = 0x21, SetOrSetAndConfigureGPIOPin = 0x22, ReadGPIOPinLevelsAndConfigurationState = 0x23, Response = 0x40, Report = 0x80, KeyActivity = 0x80, FanSpeedReport = 0x81, TemperatureSensorReport = 0x82, Error = 0xc0, }; uint8_t command; uint8_t length; uint8_t data[22]; uint16_t crc; inline Packet() {} Packet(Command command, uint8_t length, const uint8_t *data); inline std::string GetData() const { return std::string(reinterpret_cast(data), length); } }; std::queue responses; Pthreads::ThreadMutex responsesLock; Pthreads::ThreadCondition responsesCondition; std::queue keyActivity; Pthreads::ThreadMutex keyActivityLock; Pthreads::ThreadCondition keyActivityCondition; inline Packet Communicate(Packet::Command command) { return Communicate_(command, 0, reinterpret_cast(NULL)); } template Packet Communicate(Packet::Command command, Arg0 arg0); template Packet Communicate(Packet::Command command, Arg0 arg0, Arg1 arg1); template Packet Communicate(Packet::Command command, Arg0 arg0, Arg1 arg1, Arg2 arg2); void Communicate_(); Packet Communicate_(Packet::Command command, uint8_t length, const uint8_t *data); void Activity(); public: enum KeyActivity { None = 0, UpPress = 1, DownPress = 2, LeftPress = 3, RightPress = 4, EnterPress = 5, ExitPress = 6, UpRelease = 7, DownRelease = 8, LeftRelease = 9, RightRelease = 10, EnterRelease = 11, ExitRelease = 12, }; typedef void (*Callback)(KeyActivity, void *); private: Callback callback; void *data; Pthreads::Thread communicate, activity; public: enum CursorStyle { NoCursor = 0, BlinkingBlockCursor = 1, UnderscoreCursor = 2, BlinkingBlockPlusUnderscore = 3, InvertingBlinkingBlock = 4, }; enum Key { Up = 0x01, Enter = 0x02, Cancel = 0x04, Left = 0x08, Right = 0x10, Down = 0x20, }; enum Color { Green = 1, Red = 0, }; Display(const std::string &device, Callback callback = NULL, void *data = NULL); ~Display(); bool Ping(const std::string &data = std::string()); std::string Version(); inline void Store() { Communicate(Packet::StoreCurrentStateAsBootState); } inline void Clear() { Communicate(Packet::ClearLCDScreen); } inline void SetCursorPosition(uint8_t column, uint8_t row) { Communicate(Packet::SetLCDCursorPosition, column, row); } inline void SetCursorStyle(CursorStyle style) { Communicate(Packet::SetLCDCursorStyle, style); } inline void SetContrast(uint8_t contrast) { Communicate(Packet::SetLCDContrast, contrast); } inline void SetBacklight(uint8_t backlight) { Communicate(Packet::SetLCDAndKeypadBacklight, backlight); } inline void KeyReporting(uint8_t press, uint8_t release) { Communicate(Packet::ConfigureKeyReporting, press, release); } void Set(uint8_t column, uint8_t row, const std::string &data); inline void Set(uint8_t column, uint8_t row, char data) { Set(column, row, std::string(1, data)); } inline void Set(uint8_t led, Color color, uint8_t brightness) { Communicate(Packet::SetOrSetAndConfigureGPIOPin, 12 - (led << 1) - color, brightness); } friend std::ostream &operator<<(std::ostream &output, const Packet &packet); friend void operator<<(int fd, const Display::Packet &packet); friend void operator>>(int fd, Display::Packet &packet); friend void Communicate(Display *display); friend void Activity(Display *display); }; template inline Display::Packet Display::Communicate(Packet::Command command, Arg0 arg0) { uint8_t data(arg0); return Communicate_(command, 1, &data); } template <> inline Display::Packet Display::Communicate(Packet::Command command, const std::string &string) { return Communicate_(command, string.size(), reinterpret_cast(string.data())); } template inline Display::Packet Display::Communicate(Packet::Command command, Arg0 arg0, Arg1 arg1) { uint8_t data[] = { arg0, arg1 }; return Communicate_(command, 2, data); } template inline Display::Packet Display::Communicate(Packet::Command command, Arg0 arg0, Arg1 arg1, Arg2 arg2) { uint8_t data[] = { arg0, arg1, arg2 }; return Communicate_(command, 2, data); } template <> inline Display::Packet Display::Communicate(Packet::Command command, uint8_t arg0, uint8_t arg1, std::string string) { string.insert(0, 1, arg0); string.insert(1, 1, arg1); return Communicate(command, string); } #endif//_Display_hpp_