/* * Author: Josh Holtrop * Date: 2009-05-03 * See VFD.h for documentation */ #include /* perror() */ #include /* usleep() */ #include #include #include #include #include #include #include using namespace std; #include "VFD.h" VFD::VFD() { m_ppfd = -1; } bool VFD::connect(const std::string & parport) { const int mode = IEEE1284_MODE_BYTE; const int direction = 0; if ( (m_ppfd = open(parport.c_str(), O_RDWR)) < 0) { cerr << "Error opening '" << parport << "'"; perror(""); } else if (ioctl(m_ppfd, PPCLAIM, NULL)) { perror("Could not claim parallel port"); } else if (ioctl(m_ppfd, PPSETMODE, &mode)) { perror("Could not set parallel port mode"); ioctl(m_ppfd, PPRELEASE); } else if (ioctl(m_ppfd, PPDATADIR, &direction)) { perror("Could not set parallel port direction"); ioctl(m_ppfd, PPRELEASE); } else { usleep(INIT_DELAY); sendNibble(0, 0x2); /* set 4-bit mode */ sendByte(1, 0); /* set brightness */ return true; } if (m_ppfd >= 0) { close(m_ppfd); m_ppfd = -1; } return false; } void VFD::disconnect() { if (m_ppfd >= 0) { ioctl(m_ppfd, PPRELEASE); close(m_ppfd); m_ppfd = -1; } } void VFD::setPPLines(unsigned char bits) { if (m_ppfd >= 0) { ioctl(m_ppfd, PPWDATA, &bits); } } void VFD::sendNibble(unsigned char rs, unsigned char dat) { setPPLines( (rs << PP_OFFSET_RS) | (E_DISABLE << PP_OFFSET_E) | (RW_WRITE << PP_OFFSET_RW) | ((dat & 0xF) << PP_OFFSET_DATA) ); usleep(1); setPPLines( (rs << PP_OFFSET_RS) | (E_ENABLE << PP_OFFSET_E) | (RW_WRITE << PP_OFFSET_RW) | ((dat & 0xF) << PP_OFFSET_DATA) ); usleep(1); } void VFD::sendByte(unsigned char rs, unsigned char dat) { sendNibble(rs, (dat >> 4) & 0xF); sendNibble(rs, dat & 0xF); } void VFD::displayClear() { sendByte(0, 0x1); usleep(INIT_DELAY); } void VFD::cursorHome() { sendByte(0, 0x2); } void VFD::entryModeSet(unsigned char address_direction, /* LEFT|RIGHT */ unsigned char display_shift) /* ON|OFF */ { sendByte(0, 0x4 | ((address_direction & 0x1) << 1) | (display_shift & 0x1) ); } void VFD::setDisplay(unsigned char display, /* ON|OFF */ unsigned char cursor, /* ON|OFF */ unsigned char cursor_blink) /* ON|OFF */ { sendByte(0, 0x8 | ((display & 0x1) << 2) | ((cursor & 0x1) << 1) | (cursor_blink & 0x1) ); } void VFD::shift(unsigned char shift_display, /* ON|OFF */ unsigned char direction) /* LEFT|RIGHT */ { sendByte(0, 0x10 | ((shift_display & 0x1) << 3) | ((direction & 0x1) << 2) ); } void VFD::setCGAddress(unsigned char address) { sendByte(0, 0x40 | (address & 0x3F)); } void VFD::setAddress(unsigned char address) { sendByte(0, 0x80 | (address & 0x7F)); } void VFD::writeData(unsigned char data) { sendByte(1, data); }