Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
5d9be0368c
32
Conf.cpp
32
Conf.cpp
|
@ -119,8 +119,12 @@ m_hd44780PWM(false),
|
|||
m_hd44780PWMPin(),
|
||||
m_hd44780PWMBright(),
|
||||
m_hd44780PWMDim(),
|
||||
m_hd44780DisplayClock(false),
|
||||
m_hd44780UTC(false),
|
||||
m_nextionPort("/dev/ttyAMA0"),
|
||||
m_nextionBrightness(50U),
|
||||
m_nextionDisplayClock(false),
|
||||
m_nextionUTC(false),
|
||||
m_oledType(3),
|
||||
m_oledBrightness(0),
|
||||
m_oledInvert(0)
|
||||
|
@ -402,6 +406,10 @@ bool CConf::read()
|
|||
m_hd44780PWMBright = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "PWMDim") == 0)
|
||||
m_hd44780PWMDim = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "DisplayClock") == 0)
|
||||
m_hd44780DisplayClock = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "UTC") == 0)
|
||||
m_hd44780UTC = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Pins") == 0) {
|
||||
char* p = ::strtok(value, ",\r\n");
|
||||
while (p != NULL) {
|
||||
|
@ -415,6 +423,10 @@ bool CConf::read()
|
|||
m_nextionPort = value;
|
||||
else if (::strcmp(key, "Brightness") == 0)
|
||||
m_nextionBrightness = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "DisplayClock") == 0)
|
||||
m_nextionDisplayClock = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "UTC") == 0)
|
||||
m_nextionUTC = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_OLED) {
|
||||
if (::strcmp(key, "Type") == 0)
|
||||
m_oledType = (unsigned char)::atoi(value);
|
||||
|
@ -800,6 +812,16 @@ unsigned int CConf::getHD44780PWMDim() const
|
|||
return m_hd44780PWMDim;
|
||||
}
|
||||
|
||||
bool CConf::getHD44780DisplayClock() const
|
||||
{
|
||||
return m_hd44780DisplayClock;
|
||||
}
|
||||
|
||||
bool CConf::getHD44780UTC() const
|
||||
{
|
||||
return m_hd44780UTC;
|
||||
}
|
||||
|
||||
std::string CConf::getNextionPort() const
|
||||
{
|
||||
return m_nextionPort;
|
||||
|
@ -810,6 +832,16 @@ unsigned int CConf::getNextionBrightness() const
|
|||
return m_nextionBrightness;
|
||||
}
|
||||
|
||||
bool CConf::getNextionDisplayClock() const
|
||||
{
|
||||
return m_nextionDisplayClock;
|
||||
}
|
||||
|
||||
bool CConf::getNextionUTC() const
|
||||
{
|
||||
return m_nextionUTC;
|
||||
}
|
||||
|
||||
unsigned char CConf::getOLEDType() const
|
||||
{
|
||||
return m_oledType;
|
||||
|
|
8
Conf.h
8
Conf.h
|
@ -130,10 +130,14 @@ public:
|
|||
unsigned int getHD44780PWMPin() const;
|
||||
unsigned int getHD44780PWMBright() const;
|
||||
unsigned int getHD44780PWMDim() const;
|
||||
bool getHD44780DisplayClock() const;
|
||||
bool getHD44780UTC() const;
|
||||
|
||||
// The Nextion section
|
||||
std::string getNextionPort() const;
|
||||
unsigned int getNextionBrightness() const;
|
||||
bool getNextionDisplayClock() const;
|
||||
bool getNextionUTC() const;
|
||||
|
||||
// The OLED section
|
||||
unsigned char getOLEDType() const;
|
||||
|
@ -229,9 +233,13 @@ private:
|
|||
unsigned int m_hd44780PWMPin;
|
||||
unsigned int m_hd44780PWMBright;
|
||||
unsigned int m_hd44780PWMDim;
|
||||
bool m_hd44780DisplayClock;
|
||||
bool m_hd44780UTC;
|
||||
|
||||
std::string m_nextionPort;
|
||||
unsigned int m_nextionBrightness;
|
||||
bool m_nextionDisplayClock;
|
||||
bool m_nextionUTC;
|
||||
|
||||
unsigned char m_oledType;
|
||||
unsigned char m_oledBrightness;
|
||||
|
|
22
DMRSlot.cpp
22
DMRSlot.cpp
|
@ -413,7 +413,7 @@ void CDMRSlot::writeModem(unsigned char *data)
|
|||
unsigned char fid = m_rfLC->getFID();
|
||||
if (fid == FID_ETSI || fid == FID_DMRA) {
|
||||
errors = m_fec.regenerateDMR(data + 2U);
|
||||
// LogDebug("DMR Slot %u, audio sequence no. 0, errs: %u/141", m_slotNo, errors);
|
||||
LogDebug("DMR Slot %u, audio sequence no. 0, errs: %u/141", m_slotNo, errors);
|
||||
m_rfErrs += errors;
|
||||
}
|
||||
|
||||
|
@ -450,7 +450,7 @@ void CDMRSlot::writeModem(unsigned char *data)
|
|||
unsigned char fid = m_rfLC->getFID();
|
||||
if (fid == FID_ETSI || fid == FID_DMRA) {
|
||||
errors = m_fec.regenerateDMR(data + 2U);
|
||||
// LogDebug("DMR Slot %u, audio sequence no. %u, errs: %u/141", m_slotNo, m_rfN, errors);
|
||||
LogDebug("DMR Slot %u, audio sequence no. %u, errs: %u/141", m_slotNo, m_rfN, errors);
|
||||
m_rfErrs += errors;
|
||||
}
|
||||
|
||||
|
@ -533,7 +533,7 @@ void CDMRSlot::writeModem(unsigned char *data)
|
|||
unsigned char fid = m_rfLC->getFID();
|
||||
if (fid == FID_ETSI || fid == FID_DMRA) {
|
||||
errors = m_fec.regenerateDMR(data + 2U);
|
||||
// LogDebug("DMR Slot %u, audio sequence no. %u, errs: %u/141", m_slotNo, m_rfN, errors);
|
||||
LogDebug("DMR Slot %u, audio sequence no. %u, errs: %u/141", m_slotNo, m_rfN, errors);
|
||||
m_rfErrs += errors;
|
||||
}
|
||||
|
||||
|
@ -966,12 +966,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
|
||||
if (m_netState == RS_NET_AUDIO) {
|
||||
unsigned char fid = m_netLC->getFID();
|
||||
if (fid == FID_ETSI || fid == FID_DMRA) {
|
||||
unsigned int errors = m_fec.regenerateDMR(data + 2U);
|
||||
// LogDebug("DMR Slot %u, audio, errs: %u/141", m_slotNo, errors);
|
||||
m_netErrs += errors;
|
||||
}
|
||||
|
||||
if (fid == FID_ETSI || fid == FID_DMRA)
|
||||
m_netErrs += m_fec.regenerateDMR(data + 2U);
|
||||
m_netBits += 141U;
|
||||
|
||||
data[0U] = TAG_DATA;
|
||||
|
@ -1010,12 +1006,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||
return;
|
||||
|
||||
unsigned char fid = m_netLC->getFID();
|
||||
if (fid == FID_ETSI || fid == FID_DMRA) {
|
||||
unsigned int errors = m_fec.regenerateDMR(data + 2U);
|
||||
// LogDebug("DMR Slot %u, audio, errs: %u/141", m_slotNo, errors);
|
||||
m_netErrs += errors;
|
||||
}
|
||||
|
||||
if (fid == FID_ETSI || fid == FID_DMRA)
|
||||
m_netErrs += m_fec.regenerateDMR(data + 2U);
|
||||
m_netBits += 141U;
|
||||
|
||||
// Regenerate the embedded LC
|
||||
|
|
|
@ -246,7 +246,7 @@ bool CDStarControl::writeModem(unsigned char *data)
|
|||
if (m_rfN == 0U)
|
||||
CSync::addDStarSync(data + 1U);
|
||||
|
||||
// LogDebug("D-Star, audio sequence no. %u, errs: %u/48", m_rfN, errors);
|
||||
LogDebug("D-Star, audio sequence no. %u, errs: %u/48", m_rfN, errors);
|
||||
|
||||
if (m_net)
|
||||
writeNetworkDataRF(data, errors, false);
|
||||
|
@ -355,7 +355,7 @@ bool CDStarControl::writeModem(unsigned char *data)
|
|||
m_rfErrs += errors;
|
||||
m_rfBits += 48U;
|
||||
|
||||
// LogDebug("D-Star, audio sequence no. %u, errs: %u/48", m_rfN, errors);
|
||||
LogDebug("D-Star, audio sequence no. %u, errs: %u/48", m_rfN, errors);
|
||||
|
||||
if (m_net)
|
||||
writeNetworkDataRF(data, errors, false);
|
||||
|
|
249
HD44780.cpp
249
HD44780.cpp
|
@ -31,7 +31,10 @@
|
|||
const char* LISTENING = "Listening ";
|
||||
const char* DEADSPACE = " ";
|
||||
|
||||
CHD44780::CHD44780(unsigned int rows, unsigned int cols, const std::string& callsign, unsigned int dmrid, const std::vector<unsigned int>& pins, bool pwm, unsigned int pwmPin, unsigned int pwmBright, unsigned int pwmDim, bool duplex) :
|
||||
char m_buffer1[128U];
|
||||
char m_buffer2[128U];
|
||||
|
||||
CHD44780::CHD44780(unsigned int rows, unsigned int cols, const std::string& callsign, unsigned int dmrid, const std::vector<unsigned int>& pins, bool pwm, unsigned int pwmPin, unsigned int pwmBright, unsigned int pwmDim, bool displayClock, bool utc, bool duplex) :
|
||||
CDisplay(),
|
||||
m_rows(rows),
|
||||
m_cols(cols),
|
||||
|
@ -47,11 +50,15 @@ m_pwm(pwm),
|
|||
m_pwmPin(pwmPin),
|
||||
m_pwmBright(pwmBright),
|
||||
m_pwmDim(pwmDim),
|
||||
m_displayClock(displayClock),
|
||||
m_utc(utc),
|
||||
m_duplex(duplex),
|
||||
//m_duplex(true), // uncomment to force duplex display for testing!
|
||||
//m_duplex(true), // uncomment to force duplex display for testing!
|
||||
m_fd(-1),
|
||||
m_dmr(false),
|
||||
m_timer(1000U, 0U, 250U) // 250ms
|
||||
m_clockDisplayTimer(1000U, 0U, 75U), // Update the clock display every 75ms
|
||||
m_scrollTimer1(1000U, 0U, 250U), // Scroll speed for slot 1 - every 250ms
|
||||
m_scrollTimer2(1000U, 0U, 250U) // Scroll speed for slot 2 - every 250ms
|
||||
{
|
||||
assert(rows > 1U);
|
||||
assert(cols > 15U);
|
||||
|
@ -288,6 +295,9 @@ void CHD44780::adafruitLCDColour(ADAFRUIT_COLOUR colour)
|
|||
|
||||
void CHD44780::setIdleInt()
|
||||
{
|
||||
m_scrollTimer1.stop(); // Stop the scroll timer on slot 1
|
||||
m_scrollTimer2.stop(); // Stop the scroll timer on slot 2
|
||||
m_clockDisplayTimer.start(); // Start the clock display in IDLE only
|
||||
::lcdClear(m_fd);
|
||||
|
||||
#ifdef ADAFRUIT_DISPLAY
|
||||
|
@ -301,16 +311,21 @@ void CHD44780::setIdleInt()
|
|||
::pwmWrite(m_pwmPin, (m_pwmDim / 100) * 1024);
|
||||
}
|
||||
|
||||
// Print callsign and ID at on top row for all screen sizes
|
||||
::lcdPosition(m_fd, 0, 0);
|
||||
::lcdPrintf(m_fd, "%-6s / %u", m_callsign.c_str(), m_dmrid);
|
||||
::lcdPrintf(m_fd, "%-6s", m_callsign.c_str());
|
||||
::lcdPosition(m_fd, m_cols - 7, 0);
|
||||
::lcdPrintf(m_fd, "%7u", m_dmrid);
|
||||
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
// Print MMDVM and Idle on bottom row for all screen sizes
|
||||
::lcdPosition(m_fd, 0, m_rows - 1);
|
||||
::lcdPutchar(m_fd, 2);
|
||||
::lcdPutchar(m_fd, 2);
|
||||
::lcdPutchar(m_fd, 3);
|
||||
::lcdPutchar(m_fd, 4);
|
||||
::lcdPutchar(m_fd, 2);
|
||||
::lcdPuts(m_fd, " Idle");
|
||||
::lcdPosition(m_fd, m_cols - 4, m_rows - 1);
|
||||
::lcdPuts(m_fd, "Idle"); // Gets overwritten by clock on 2 line screen
|
||||
|
||||
m_dmr = false;
|
||||
}
|
||||
|
@ -323,6 +338,9 @@ void CHD44780::setErrorInt(const char* text)
|
|||
adafruitLCDColour(AC_RED);
|
||||
#endif
|
||||
|
||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||
m_scrollTimer1.stop(); // Stop the scroll timer on slot 1
|
||||
m_scrollTimer2.stop(); // Stop the scroll timer on slot 2
|
||||
::lcdClear(m_fd);
|
||||
|
||||
if (m_pwm) {
|
||||
|
@ -351,6 +369,9 @@ void CHD44780::setLockoutInt()
|
|||
adafruitLCDColour(AC_RED);
|
||||
#endif
|
||||
|
||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||
m_scrollTimer1.stop(); // Stop the scroll timer on slot 1
|
||||
m_scrollTimer2.stop(); // Stop the scroll timer on slot 2
|
||||
::lcdClear(m_fd);
|
||||
|
||||
if (m_pwm) {
|
||||
|
@ -385,6 +406,7 @@ void CHD44780::writeDStarInt(const char* my1, const char* my2, const char* your,
|
|||
adafruitLCDColour(AC_RED);
|
||||
#endif
|
||||
|
||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||
::lcdClear(m_fd);
|
||||
|
||||
if (m_pwm) {
|
||||
|
@ -398,45 +420,43 @@ void CHD44780::writeDStarInt(const char* my1, const char* my2, const char* your,
|
|||
::lcdPuts(m_fd, "D-Star");
|
||||
|
||||
if (m_rows == 2U && m_cols == 16U) {
|
||||
char buffer[16U];
|
||||
::sprintf(buffer, "%s %.8s/%.4s", type, my1, my2);
|
||||
::sprintf(m_buffer1, "%s %.8s/%.4s", type, my1, my2);
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, buffer);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
} else if (m_rows == 4U && m_cols == 16U) {
|
||||
char buffer[16U];
|
||||
::sprintf(buffer, "%s %.8s/%.4s", type, my1, my2);
|
||||
::sprintf(m_buffer1, "%s %.8s/%.4s", type, my1, my2);
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, buffer);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
|
||||
if (strcmp(reflector, " ") == 0)
|
||||
::sprintf(buffer, "%.8s", your);
|
||||
::sprintf(m_buffer1, "%.8s", your);
|
||||
else
|
||||
::sprintf(buffer, "%.8s<%.8s", your, reflector);
|
||||
::sprintf(m_buffer1, "%.8s<%.8s", your, reflector);
|
||||
|
||||
::lcdPosition(m_fd, 0, 2);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, buffer);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
} else if (m_rows == 4U && m_cols == 20U) {
|
||||
char buffer[20U];
|
||||
::sprintf(buffer, "%s %.8s/%.4s >", type, my1, my2);
|
||||
char m_buffer1[20U];
|
||||
::sprintf(m_buffer1, "%s %.8s/%.4s >", type, my1, my2);
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, buffer);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
|
||||
if (strcmp(reflector, " ") == 0)
|
||||
::sprintf(buffer, "%.8s", your);
|
||||
::sprintf(m_buffer1, "%.8s", your);
|
||||
else
|
||||
::sprintf(buffer, "%.8s <- %.8s", your, reflector);
|
||||
::sprintf(m_buffer1, "%.8s <- %.8s", your, reflector);
|
||||
|
||||
::lcdPosition(m_fd, 0, 2);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, buffer);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
} else if (m_rows == 2 && m_cols == 40U) {
|
||||
char buffer[40U];
|
||||
char m_buffer1[40U];
|
||||
if (strcmp(reflector, " ") == 0)
|
||||
::sprintf(buffer, "%s %.8s/%.4s > %.8s", type, my1, my2, your);
|
||||
::sprintf(m_buffer1, "%s %.8s/%.4s > %.8s", type, my1, my2, your);
|
||||
else
|
||||
::sprintf(buffer, "%s %.8s/%.4s > %.8s via %.8s", type, my1, my2, your, reflector);
|
||||
::sprintf(m_buffer1, "%s %.8s/%.4s > %.8s via %.8s", type, my1, my2, your, reflector);
|
||||
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, buffer);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
}
|
||||
|
||||
m_dmr = false;
|
||||
|
@ -448,6 +468,8 @@ void CHD44780::clearDStarInt()
|
|||
adafruitLCDColour(AC_PURPLE);
|
||||
#endif
|
||||
|
||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||
|
||||
if (m_rows == 2U && m_cols == 16U) {
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, LISTENING);
|
||||
|
@ -471,10 +493,10 @@ void CHD44780::clearDStarInt()
|
|||
|
||||
void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type)
|
||||
{
|
||||
char buffer[128]; // force 128 char buffer - we're never getting that far but stops us overflowing it!
|
||||
assert(type != NULL);
|
||||
|
||||
if (!m_dmr) {
|
||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||
::lcdClear(m_fd);
|
||||
|
||||
#ifdef ADAFRUIT_DISPLAY
|
||||
|
@ -491,21 +513,24 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro
|
|||
if (m_duplex) {
|
||||
if (m_rows > 2U) {
|
||||
::lcdPosition(m_fd, 0, (m_rows / 2) - 2);
|
||||
::sprintf(buffer, "%s%s", "DMR", DEADSPACE);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, buffer);
|
||||
::sprintf(m_buffer1, "%s%s", "DMR", DEADSPACE);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
}
|
||||
|
||||
if (slotNo == 1U) {
|
||||
m_scrollTimer2.stop();
|
||||
::lcdPosition(m_fd, 0, (m_rows / 2));
|
||||
::lcdPrintf(m_fd, "2 %.*s", m_cols - 2U, LISTENING);
|
||||
} else {
|
||||
m_scrollTimer1.stop();
|
||||
::lcdPosition(m_fd, 0, (m_rows / 2) - 1);
|
||||
::lcdPrintf(m_fd, "1 %.*s", m_cols - 2U, LISTENING);
|
||||
}
|
||||
} else {
|
||||
m_scrollTimer2.stop();
|
||||
::lcdPosition(m_fd, 0, (m_rows / 2) - 1);
|
||||
::sprintf(buffer, "%s%s", "DMR", DEADSPACE);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, buffer);
|
||||
::sprintf(m_buffer1, "%s%s", "DMR", DEADSPACE);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
::lcdPosition(m_fd, 0, (m_rows / 2));
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, LISTENING);
|
||||
}
|
||||
|
@ -519,49 +544,51 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro
|
|||
if (slotNo == 1U) {
|
||||
::lcdPosition(m_fd, 0, (m_rows / 2) - 1);
|
||||
::lcdPuts(m_fd, "1 ");
|
||||
::sprintf(buffer, "%s > %s%s", src.c_str(), dst.c_str(), DEADSPACE);
|
||||
::sprintf(m_buffer1, "%s > %s%s ", src.c_str(), group ? "TG" : "", dst.c_str());
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols - 2U, m_buffer1);
|
||||
|
||||
// Thread this out?
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols - 2U, buffer);
|
||||
|
||||
if (m_cols > 16) {
|
||||
::lcdCharDef(m_fd, 6, group ? tgChar : privChar);
|
||||
::lcdCharDef(m_fd, 5, strcmp(type, "R") == 0 ? rfChar : ipChar);
|
||||
::lcdPosition(m_fd, m_cols - 3U, (m_rows / 2) - 1);
|
||||
::lcdPuts(m_fd, " ");
|
||||
::lcdPutchar(m_fd, 6);
|
||||
::lcdPutchar(m_fd, 5);
|
||||
// Start the scroll timer on slot 1 if text in m_buffer1 will not fit in the space available
|
||||
if (strlen(m_buffer1) - 5 > m_cols - 5 ) {
|
||||
m_scrollTimer1.start();
|
||||
}
|
||||
|
||||
::lcdCharDef(m_fd, 6, group ? tgChar : privChar);
|
||||
::lcdCharDef(m_fd, 5, strcmp(type, "R") == 0 ? rfChar : ipChar);
|
||||
::lcdPosition(m_fd, m_cols - 3U, (m_rows / 2) - 1);
|
||||
::lcdPuts(m_fd, " ");
|
||||
::lcdPutchar(m_fd, 6);
|
||||
::lcdPutchar(m_fd, 5);
|
||||
} else {
|
||||
::lcdPosition(m_fd, 0, (m_rows / 2));
|
||||
::lcdPuts(m_fd, "2 ");
|
||||
::sprintf(buffer, "%s > %s%s", src.c_str(), dst.c_str(), DEADSPACE);
|
||||
::sprintf(m_buffer2, "%s > %s%s ", src.c_str(), group ? "TG" : "", dst.c_str());
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols - 2U, m_buffer2);
|
||||
|
||||
// Thread this out?
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols - 2U, buffer);
|
||||
|
||||
if (m_cols > 16) {
|
||||
::lcdCharDef(m_fd, 6, group ? tgChar : privChar);
|
||||
::lcdCharDef(m_fd, 5, strcmp(type, "R") == 0 ? rfChar : ipChar);
|
||||
::lcdPosition(m_fd, m_cols - 3U, (m_rows / 2));
|
||||
::lcdPuts(m_fd, " ");
|
||||
::lcdPutchar(m_fd, 6);
|
||||
::lcdPutchar(m_fd, 5);
|
||||
// Start the scroll timer on slot 2 if text in m_buffer2 will not fit in the space available
|
||||
if (strlen(m_buffer2) - 5 > m_cols - 5 ) {
|
||||
m_scrollTimer2.start();
|
||||
}
|
||||
|
||||
::lcdCharDef(m_fd, 6, group ? tgChar : privChar);
|
||||
::lcdCharDef(m_fd, 5, strcmp(type, "R") == 0 ? rfChar : ipChar);
|
||||
::lcdPosition(m_fd, m_cols - 3U, (m_rows / 2));
|
||||
::lcdPuts(m_fd, " ");
|
||||
::lcdPutchar(m_fd, 6);
|
||||
::lcdPutchar(m_fd, 5);
|
||||
}
|
||||
} else {
|
||||
::lcdPosition(m_fd, 0, (m_rows / 2) - 1);
|
||||
::lcdPutchar(m_fd, 0);
|
||||
::sprintf(buffer, " %s%s", src.c_str(), DEADSPACE);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols - 4U, buffer);
|
||||
::sprintf(m_buffer2, " %s%s", src.c_str(), DEADSPACE);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols - 4U, m_buffer2);
|
||||
::lcdCharDef(m_fd, 5, strcmp(type, "R") == 0 ? rfChar : ipChar);
|
||||
::lcdPosition(m_fd, m_cols - 1U, (m_rows / 2) - 1);
|
||||
::lcdPutchar(m_fd, 5);
|
||||
|
||||
::lcdPosition(m_fd, 0, (m_rows / 2));
|
||||
::lcdPutchar(m_fd, 1);
|
||||
::sprintf(buffer, " %s%s", dst.c_str(), DEADSPACE);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols - 4U, buffer);
|
||||
::sprintf(m_buffer2, " %s%s", dst.c_str(), DEADSPACE);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols - 4U, m_buffer2);
|
||||
::lcdCharDef(m_fd, 6, group ? tgChar : privChar);
|
||||
::lcdPosition(m_fd, m_cols - 1U, (m_rows / 2));
|
||||
::lcdPutchar(m_fd, 6);
|
||||
|
@ -571,26 +598,29 @@ void CHD44780::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro
|
|||
|
||||
void CHD44780::clearDMRInt(unsigned int slotNo)
|
||||
{
|
||||
char buffer[128]; // force 128 char buffer - we're never getting that far but stops us overflowing it!
|
||||
|
||||
#ifdef ADAFRUIT_DISPLAY
|
||||
adafruitLCDColour(AC_PURPLE);
|
||||
#endif
|
||||
|
||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||
|
||||
if (m_duplex) {
|
||||
if (slotNo == 1U) {
|
||||
m_scrollTimer1.stop(); // Stop the scroll timer on slot 1
|
||||
::lcdPosition(m_fd, 0, 0);
|
||||
::lcdPrintf(m_fd, "1 %.*s", m_cols - 2U, LISTENING);
|
||||
} else {
|
||||
m_scrollTimer2.stop(); // Stop the scroll timer on slot 2
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::lcdPrintf(m_fd, "2 %.*s", m_cols - 2U, LISTENING);
|
||||
}
|
||||
} else {
|
||||
::lcdPosition(m_fd, 0, (m_rows / 2) - 1);
|
||||
::sprintf(buffer, "%s%s", "DMR", DEADSPACE);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, buffer);
|
||||
::lcdPosition(m_fd, 0, (m_rows / 2));
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, LISTENING);
|
||||
m_scrollTimer2.stop(); // Stop the scroll timer on slot 2
|
||||
::lcdPosition(m_fd, 0, (m_rows / 2) - 1);
|
||||
::sprintf(m_buffer2, "%s%s", "DMR", DEADSPACE);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer2);
|
||||
::lcdPosition(m_fd, 0, (m_rows / 2));
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, LISTENING);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -605,6 +635,7 @@ void CHD44780::writeFusionInt(const char* source, const char* dest, const char*
|
|||
adafruitLCDColour(AC_RED);
|
||||
#endif
|
||||
|
||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||
::lcdClear(m_fd);
|
||||
|
||||
if (m_pwm) {
|
||||
|
@ -618,34 +649,34 @@ void CHD44780::writeFusionInt(const char* source, const char* dest, const char*
|
|||
::lcdPuts(m_fd, "System Fusion");
|
||||
|
||||
if (m_rows == 2U && m_cols == 16U) {
|
||||
char buffer[16U];
|
||||
::sprintf(buffer, "%.10s >", source);
|
||||
char m_buffer1[16U];
|
||||
::sprintf(m_buffer1, "%.10s >", source);
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, buffer);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
} else if (m_rows == 4U && m_cols == 16U) {
|
||||
char buffer[16U];
|
||||
::sprintf(buffer, "%.10s >", source);
|
||||
char m_buffer1[16U];
|
||||
::sprintf(m_buffer1, "%.10s >", source);
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, buffer);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
|
||||
::sprintf(buffer, "%.10s", dest);
|
||||
::sprintf(m_buffer1, "%.10s", dest);
|
||||
::lcdPosition(m_fd, 0, 2);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, buffer);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
} else if (m_rows == 4U && m_cols == 20U) {
|
||||
char buffer[20U];
|
||||
::sprintf(buffer, "%.10s >", source);
|
||||
char m_buffer1[20U];
|
||||
::sprintf(m_buffer1, "%.10s >", source);
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, buffer);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
|
||||
::sprintf(buffer, "%.10s", dest);
|
||||
::sprintf(m_buffer1, "%.10s", dest);
|
||||
::lcdPosition(m_fd, 0, 2);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, buffer);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
} else if (m_rows == 2 && m_cols == 40U) {
|
||||
char buffer[40U];
|
||||
::sprintf(buffer, "%.10s > %.10s", source, dest);
|
||||
char m_buffer1[40U];
|
||||
::sprintf(m_buffer1, "%.10s > %.10s", source, dest);
|
||||
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, buffer);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, m_buffer1);
|
||||
}
|
||||
|
||||
m_dmr = false;
|
||||
|
@ -657,6 +688,8 @@ void CHD44780::clearFusionInt()
|
|||
adafruitLCDColour(AC_PURPLE);
|
||||
#endif
|
||||
|
||||
m_clockDisplayTimer.stop(); // Stop the clock display
|
||||
|
||||
if (m_rows == 2U && m_cols == 16U) {
|
||||
::lcdPosition(m_fd, 0, 1);
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols, LISTENING);
|
||||
|
@ -680,13 +713,59 @@ void CHD44780::clearFusionInt()
|
|||
|
||||
void CHD44780::clockInt(unsigned int ms)
|
||||
{
|
||||
m_timer.clock(ms);
|
||||
if (m_timer.isRunning() && m_timer.hasExpired()) {
|
||||
// Do work every 250ms here
|
||||
m_clockDisplayTimer.clock(ms);
|
||||
m_scrollTimer1.clock(ms);
|
||||
m_scrollTimer2.clock(ms);
|
||||
|
||||
// Start the timer with m_timer.start();
|
||||
// and stop it with m_timer.stop();
|
||||
m_timer.start();
|
||||
// Idle clock display
|
||||
if (m_displayClock && m_clockDisplayTimer.isRunning() && m_clockDisplayTimer.hasExpired()) {
|
||||
time_t currentTime;
|
||||
struct tm *Time;
|
||||
time(¤tTime);
|
||||
|
||||
if (m_utc) {
|
||||
Time = gmtime(¤tTime);
|
||||
} else {
|
||||
Time = localtime(¤tTime);
|
||||
}
|
||||
|
||||
int Day = Time->tm_mday;
|
||||
int Month = Time->tm_mon + 1;
|
||||
int Year = Time->tm_year + 1900;
|
||||
int Hour = Time->tm_hour;
|
||||
int Min = Time->tm_min;
|
||||
int Sec = Time->tm_sec;
|
||||
|
||||
if (m_cols == 16U && m_rows == 2U) {
|
||||
::lcdPosition(m_fd, m_cols - 8, 1);
|
||||
} else {
|
||||
::lcdPosition(m_fd, (m_cols - 8) / 2, m_rows == 2 ? 1 : 2);
|
||||
}
|
||||
::lcdPrintf(m_fd, "%02d:%02d:%02d", Hour, Min, Sec);
|
||||
|
||||
if (m_cols != 16U && m_rows != 2U) {
|
||||
::lcdPosition(m_fd, (m_cols - 8) / 2, m_rows == 2 ? 0 : 1);
|
||||
::lcdPrintf(m_fd, "%02d/%02d/%2d", Day, Month, Year%100);
|
||||
}
|
||||
m_clockDisplayTimer.start();
|
||||
}
|
||||
|
||||
// Slot 1 scrolling
|
||||
if (m_scrollTimer1.isRunning() && m_scrollTimer1.hasExpired()) {
|
||||
strncat(m_buffer1, m_buffer1, 1); // Move the first character to the end of the buffer
|
||||
memmove(m_buffer1, m_buffer1 + 1, strlen(m_buffer1)); // Strip the first character
|
||||
::lcdPosition(m_fd, 2, (m_rows / 2) - 1); // Position on the LCD
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols - 5U, m_buffer1); // Print it out
|
||||
m_scrollTimer1.start(); // Restart the scroll timer
|
||||
}
|
||||
|
||||
// Slot 2 scrolling
|
||||
if (m_scrollTimer2.isRunning() && m_scrollTimer2.hasExpired()) {
|
||||
strncat(m_buffer2, m_buffer2, 1);
|
||||
memmove(m_buffer2, m_buffer2 + 1, strlen(m_buffer2));
|
||||
::lcdPosition(m_fd, 2, (m_rows / 2));
|
||||
::lcdPrintf(m_fd, "%.*s", m_cols - 5U, m_buffer2);
|
||||
m_scrollTimer2.start();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ enum ADAFRUIT_COLOUR {
|
|||
class CHD44780 : public CDisplay
|
||||
{
|
||||
public:
|
||||
CHD44780(unsigned int rows, unsigned int cols, const std::string& callsign, unsigned int dmrid, const std::vector<unsigned int>& pins, bool pwm, unsigned int pwmPin, unsigned int pwmBright, unsigned int pwmDim, bool duplex);
|
||||
CHD44780(unsigned int rows, unsigned int cols, const std::string& callsign, unsigned int dmrid, const std::vector<unsigned int>& pins, bool pwm, unsigned int pwmPin, unsigned int pwmBright, unsigned int pwmDim, bool displayClock, bool utc, bool duplex);
|
||||
virtual ~CHD44780();
|
||||
|
||||
virtual bool open();
|
||||
|
@ -91,10 +91,14 @@ private:
|
|||
unsigned int m_pwmPin;
|
||||
unsigned int m_pwmBright;
|
||||
unsigned int m_pwmDim;
|
||||
bool m_displayClock;
|
||||
bool m_utc;
|
||||
bool m_duplex;
|
||||
int m_fd;
|
||||
bool m_dmr;
|
||||
CTimer m_timer;
|
||||
CTimer m_clockDisplayTimer;
|
||||
CTimer m_scrollTimer1;
|
||||
CTimer m_scrollTimer2;
|
||||
|
||||
#ifdef ADAFRUIT_DISPLAY
|
||||
void adafruitLCDSetup();
|
||||
|
|
58
HD44780.layouts
Normal file
58
HD44780.layouts
Normal file
|
@ -0,0 +1,58 @@
|
|||
IDLE SCREEN LAYOUTS
|
||||
-------------------
|
||||
|
||||
16 x 2
|
||||
------
|
||||
|
||||
With clock Without clock
|
||||
---------- -------------
|
||||
|
||||
0 1 0 1
|
||||
0123456789012345 0123456789012345
|
||||
+----------------+ +----------------+
|
||||
0|AAAAAA NNNNNNN| 0|AAAAAA NNNNNNN|
|
||||
1|MMDVM HH:MM:SS| 1|MMDVM Idle|
|
||||
+----------------+ +----------------+
|
||||
|
||||
40 x 2
|
||||
------
|
||||
|
||||
With clock Without clock
|
||||
---------- -------------
|
||||
|
||||
0 1 2 3 0 1 2 3
|
||||
0123456789012345678901234567890123456789 0123456789012345678901234567890123456789
|
||||
+----------------------------------------+ +----------------------------------------+
|
||||
0|AAAAAA DD/MM/YY NNNNNNN| 0|AAAAAA NNNNNNN|
|
||||
1|MMDVM HH:MM:SS Idle| 1|MMDVM Idle|
|
||||
+----------------------------------------+ +----------------------------------------+
|
||||
|
||||
16 x 4
|
||||
------
|
||||
|
||||
With clock Without clock
|
||||
---------- -------------
|
||||
|
||||
0 1 0 1
|
||||
0123456789012345 0123456789012345
|
||||
+----------------+ +----------------+
|
||||
0|AAAAAA NNNNNNN| 0|AAAAAA NNNNNNN|
|
||||
1| DD/MM/YY | 1| |
|
||||
2| HH:MM:SS | 2| |
|
||||
3|MMDVM Idle| 3|MMDVM Idle|
|
||||
+----------------+ +----------------+
|
||||
|
||||
20 x 4
|
||||
------
|
||||
|
||||
With clock Without clock
|
||||
---------- -------------
|
||||
|
||||
0 1 0 1
|
||||
01234567890123456479 01234567890123456789
|
||||
+--------------------+ +--------------------+
|
||||
0|AAAAAA NNNNNNN| 0|AAAAAA NNNNNNN|
|
||||
1| DD/MM/YY | 1| |
|
||||
2| HH:MM:SS | 2| |
|
||||
3|MMDVM Idle| 3|MMDVM Idle|
|
||||
+--------------------+ +--------------------+
|
|
@ -95,18 +95,21 @@ Pins=11,10,0,1,2,3
|
|||
# For Adafruit i2c HD44780
|
||||
# Pins=115,113,112,111,110,109
|
||||
|
||||
# PWM brightness control
|
||||
PWM=1
|
||||
# PWM backlight
|
||||
PWM=0
|
||||
PWMPin=21
|
||||
PWMBright=100
|
||||
PWMDim=16
|
||||
DisplayClock=1
|
||||
UTC=0
|
||||
|
||||
[Nextion]
|
||||
Port=/dev/ttyAMA0
|
||||
Brightness=50
|
||||
DisplayClock=1
|
||||
UTC=0
|
||||
|
||||
[OLED]
|
||||
Type=3
|
||||
Brightness=0
|
||||
Invert=0
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "NullDisplay.h"
|
||||
#include "YSFControl.h"
|
||||
#include "Nextion.h"
|
||||
#include "Thread.h"
|
||||
|
||||
#if defined(HD44780)
|
||||
#include "HD44780.h"
|
||||
|
@ -255,6 +256,7 @@ int CMMDVMHost::run()
|
|||
LogInfo(" Time: %u mins", time);
|
||||
|
||||
m_cwIdTimer.setTimeout(time * 60U);
|
||||
m_cwIdTimer.start();
|
||||
}
|
||||
|
||||
CTimer dmrBeaconTimer(1000U, 4U);
|
||||
|
@ -551,9 +553,12 @@ int CMMDVMHost::run()
|
|||
|
||||
m_cwIdTimer.clock(ms);
|
||||
if (m_cwIdTimer.isRunning() && m_cwIdTimer.hasExpired()) {
|
||||
if (m_mode == MODE_IDLE && !m_modem->hasTX())
|
||||
if (m_mode == MODE_IDLE && !m_modem->hasTX()){
|
||||
LogDebug("sending CW ID");
|
||||
m_modem->sendCWId(m_callsign);
|
||||
m_cwIdTimer.start();
|
||||
|
||||
m_cwIdTimer.start(); //reset only after sending ID, timer-overflow after 49 days doesnt matter
|
||||
}
|
||||
}
|
||||
|
||||
dmrBeaconTimer.clock(ms);
|
||||
|
@ -568,13 +573,8 @@ int CMMDVMHost::run()
|
|||
m_dmrTXTimer.stop();
|
||||
}
|
||||
|
||||
if (ms < 5U) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
::Sleep(5UL); // 5ms
|
||||
#else
|
||||
::usleep(5000); // 5ms
|
||||
#endif
|
||||
}
|
||||
if (ms < 5U)
|
||||
CThread::sleep(5U);
|
||||
}
|
||||
|
||||
LogMessage("MMDVMHost-%s is exiting on receipt of SIGHUP1", VERSION);
|
||||
|
@ -791,11 +791,16 @@ void CMMDVMHost::createDisplay()
|
|||
} else if (type == "Nextion") {
|
||||
std::string port = m_conf.getNextionPort();
|
||||
unsigned int brightness = m_conf.getNextionBrightness();
|
||||
bool displayClock = m_conf.getNextionDisplayClock();
|
||||
bool utc = m_conf.getNextionUTC();
|
||||
|
||||
LogInfo(" Port: %s", port.c_str());
|
||||
LogInfo(" Brightness: %u", brightness);
|
||||
LogInfo(" Clock Display: %s", displayClock ? "yes" : "no");
|
||||
if (displayClock)
|
||||
LogInfo(" Display UTC: %s", utc ? "yes" : "no");
|
||||
|
||||
m_display = new CNextion(m_callsign, dmrid, port, brightness);
|
||||
m_display = new CNextion(m_callsign, dmrid, port, brightness, displayClock, utc);
|
||||
#if defined(HD44780)
|
||||
} else if (type == "HD44780") {
|
||||
unsigned int rows = m_conf.getHD44780Rows();
|
||||
|
@ -805,20 +810,26 @@ void CMMDVMHost::createDisplay()
|
|||
unsigned int pwmPin = m_conf.getHD44780PWMPin();
|
||||
unsigned int pwmBright = m_conf.getHD44780PWMBright();
|
||||
unsigned int pwmDim = m_conf.getHD44780PWMDim();
|
||||
bool displayClock = m_conf.getHD44780DisplayClock();
|
||||
bool utc = m_conf.getHD44780UTC();
|
||||
|
||||
if (pins.size() == 6U) {
|
||||
LogInfo(" Rows: %u", rows);
|
||||
LogInfo(" Columns: %u", columns);
|
||||
LogInfo(" Pins: %u,%u,%u,%u,%u,%u", pins.at(0U), pins.at(1U), pins.at(2U), pins.at(3U), pins.at(4U), pins.at(5U));
|
||||
|
||||
LogInfo(" PWM Backlight: %s", pwm ? "yes" : "no");
|
||||
if (pwm) {
|
||||
LogInfo("PWM Brightness Control Enabled");
|
||||
LogInfo(" PWM Pin: %u", pwmPin);
|
||||
LogInfo(" PWM Bright: %u", pwmBright);
|
||||
LogInfo(" PWM Dim: %u", pwmDim);
|
||||
}
|
||||
|
||||
m_display = new CHD44780(rows, columns, m_callsign, dmrid, pins, pwm, pwmPin, pwmBright, pwmDim, m_duplex);
|
||||
LogInfo(" Clock Display: %s", displayClock ? "yes" : "no");
|
||||
if (displayClock)
|
||||
LogInfo(" Display UTC: %s", utc ? "yes" : "no");
|
||||
|
||||
m_display = new CHD44780(rows, columns, m_callsign, dmrid, pins, pwm, pwmPin, pwmBright, pwmDim, displayClock, utc, m_duplex);
|
||||
}
|
||||
#endif
|
||||
#if defined(OLED)
|
||||
|
|
|
@ -187,6 +187,7 @@
|
|||
<ClInclude Include="StopWatch.h" />
|
||||
<ClInclude Include="Sync.h" />
|
||||
<ClInclude Include="TFTSerial.h" />
|
||||
<ClInclude Include="Thread.h" />
|
||||
<ClInclude Include="Timer.h" />
|
||||
<ClInclude Include="UDPSocket.h" />
|
||||
<ClInclude Include="Utils.h" />
|
||||
|
@ -236,6 +237,7 @@
|
|||
<ClCompile Include="StopWatch.cpp" />
|
||||
<ClCompile Include="Sync.cpp" />
|
||||
<ClCompile Include="TFTSerial.cpp" />
|
||||
<ClCompile Include="Thread.cpp" />
|
||||
<ClCompile Include="Timer.cpp" />
|
||||
<ClCompile Include="UDPSocket.cpp" />
|
||||
<ClCompile Include="Utils.cpp" />
|
||||
|
|
|
@ -164,6 +164,9 @@
|
|||
<ClInclude Include="YSFNetwork.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Thread.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="BPTC19696.cpp">
|
||||
|
@ -301,5 +304,8 @@
|
|||
<ClCompile Include="YSFNetwork.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Thread.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
8
Makefile
8
Makefile
|
@ -2,15 +2,15 @@
|
|||
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
CFLAGS = -g -O3 -Wall -std=c++0x
|
||||
LIBS =
|
||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread
|
||||
LIBS = -lpthread
|
||||
LDFLAGS = -g
|
||||
|
||||
OBJECTS = \
|
||||
AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \
|
||||
DMRShortLC.o DMRSlot.o DMRSlotType.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o Log.o MMDVMHost.o Modem.o \
|
||||
Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Timer.o UDPSocket.o Utils.o YSFControl.o YSFConvolution.o \
|
||||
YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||
Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o \
|
||||
YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||
|
||||
all: MMDVMHost
|
||||
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
# Support for the Adafruit i2c 16 x 2 RGB LCD Pi Plate
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
CFLAGS = -g -O3 -Wall -std=c++0x -DHD44780 -DADAFRUIT_DISPLAY -I/usr/local/include
|
||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHD44780 -DADAFRUIT_DISPLAY -I/usr/local/include
|
||||
LIBS = -lwiringPi -lwiringPiDev -lpthread
|
||||
LDFLAGS = -g -L/usr/local/lib
|
||||
|
||||
OBJECTS = \
|
||||
AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \
|
||||
DMRShortLC.o DMRSlot.o DMRSlotType.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o Log.o MMDVMHost.o \
|
||||
Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Timer.o UDPSocket.o Utils.o YSFControl.o \
|
||||
Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o \
|
||||
YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||
|
||||
all: MMDVMHost
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
CFLAGS = -g -O3 -Wall -std=c++0x -DHD44780 -I/usr/local/include
|
||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DHD44780 -I/usr/local/include
|
||||
LIBS = -lwiringPi -lwiringPiDev -lpthread
|
||||
LDFLAGS = -g -L/usr/local/lib
|
||||
|
||||
OBJECTS = \
|
||||
AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \
|
||||
DMRShortLC.o DMRSlot.o DMRSlotType.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o Log.o MMDVMHost.o \
|
||||
Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Timer.o UDPSocket.o Utils.o YSFControl.o \
|
||||
Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o \
|
||||
YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||
|
||||
all: MMDVMHost
|
||||
|
|
|
@ -2,14 +2,14 @@
|
|||
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
CFLAGS = -g -O3 -Wall -std=c++0x -DOLED -I/usr/local/include
|
||||
LIBS = -lArduiPi_OLED
|
||||
CFLAGS = -g -O3 -Wall -std=c++0x -pthread -DOLED -I/usr/local/include
|
||||
LIBS = -lArduiPi_OLED -lpthread
|
||||
LDFLAGS = -g -L/usr/local/lib
|
||||
|
||||
OBJECTS = \
|
||||
AMBEFEC.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRIPSC.o DMRLookup.o DMRLC.o \
|
||||
DMRShortLC.o DMRSlot.o DMRSlotType.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o Golay24128.o Hamming.o OLED.o Log.o MMDVMHost.o \
|
||||
Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Timer.o UDPSocket.o Utils.o YSFControl.o \
|
||||
Modem.o Nextion.o NullDisplay.o QR1676.o RS129.o SerialController.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o Utils.o YSFControl.o \
|
||||
YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
|
||||
|
||||
all: MMDVMHost
|
||||
|
|
29
Modem.cpp
29
Modem.cpp
|
@ -20,6 +20,7 @@
|
|||
#include "DMRDefines.h"
|
||||
#include "YSFDefines.h"
|
||||
#include "Defines.h"
|
||||
#include "Thread.h"
|
||||
#include "Modem.h"
|
||||
#include "Utils.h"
|
||||
#include "Log.h"
|
||||
|
@ -717,11 +718,7 @@ bool CModem::readVersion()
|
|||
return false;
|
||||
|
||||
for (unsigned int count = 0U; count < MAX_RESPONSES; count++) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
::Sleep(10UL);
|
||||
#else
|
||||
::usleep(10000UL);
|
||||
#endif
|
||||
CThread::sleep(10U);
|
||||
RESP_TYPE_MMDVM resp = getResponse();
|
||||
if (resp == RTM_OK && m_buffer[2U] == MMDVM_GET_VERSION) {
|
||||
LogInfo("MMDVM protocol version: %u, description: %.*s", m_buffer[3U], m_length - 4U, m_buffer + 4U);
|
||||
|
@ -729,11 +726,7 @@ bool CModem::readVersion()
|
|||
}
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
::Sleep(1000UL); // 1s
|
||||
#else
|
||||
::sleep(1UL); // 1s
|
||||
#endif
|
||||
CThread::sleep(1000U);
|
||||
}
|
||||
|
||||
LogError("Unable to read the firmware version after six attempts");
|
||||
|
@ -802,13 +795,9 @@ bool CModem::setConfig()
|
|||
unsigned int count = 0U;
|
||||
RESP_TYPE_MMDVM resp;
|
||||
do {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
::Sleep(10UL);
|
||||
#else
|
||||
::usleep(10000UL);
|
||||
#endif
|
||||
resp = getResponse();
|
||||
CThread::sleep(10U);
|
||||
|
||||
resp = getResponse();
|
||||
if (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK) {
|
||||
count++;
|
||||
if (count >= MAX_RESPONSES) {
|
||||
|
@ -861,13 +850,9 @@ bool CModem::setFrequency()
|
|||
unsigned int count = 0U;
|
||||
RESP_TYPE_MMDVM resp;
|
||||
do {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
::Sleep(10UL);
|
||||
#else
|
||||
::usleep(10000UL);
|
||||
#endif
|
||||
resp = getResponse();
|
||||
CThread::sleep(10U);
|
||||
|
||||
resp = getResponse();
|
||||
if (resp == RTM_OK && m_buffer[2U] != MMDVM_ACK && m_buffer[2U] != MMDVM_NAK) {
|
||||
count++;
|
||||
if (count >= MAX_RESPONSES) {
|
||||
|
|
49
Nextion.cpp
49
Nextion.cpp
|
@ -22,14 +22,18 @@
|
|||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
|
||||
CNextion::CNextion(const std::string& callsign, unsigned int dmrid, const std::string& port, unsigned int brightness) :
|
||||
CNextion::CNextion(const std::string& callsign, unsigned int dmrid, const std::string& port, unsigned int brightness, bool displayClock, bool utc) :
|
||||
CDisplay(),
|
||||
m_callsign(callsign),
|
||||
m_dmrid(dmrid),
|
||||
m_serial(port, SERIAL_9600),
|
||||
m_brightness(brightness),
|
||||
m_mode(MODE_IDLE)
|
||||
m_mode(MODE_IDLE),
|
||||
m_displayClock(displayClock),
|
||||
m_utc(utc),
|
||||
m_clockDisplayTimer(1000U, 0U, 400U)
|
||||
{
|
||||
assert(brightness >= 0U && brightness <= 100U);
|
||||
}
|
||||
|
@ -67,6 +71,8 @@ void CNextion::setIdleInt()
|
|||
sendCommand(command);
|
||||
sendCommand("t1.txt=\"MMDVM IDLE\"");
|
||||
|
||||
m_clockDisplayTimer.start();
|
||||
|
||||
m_mode = MODE_IDLE;
|
||||
}
|
||||
|
||||
|
@ -82,6 +88,8 @@ void CNextion::setErrorInt(const char* text)
|
|||
sendCommand(command);
|
||||
sendCommand("t1.txt=\"ERROR\"");
|
||||
|
||||
m_clockDisplayTimer.stop();
|
||||
|
||||
m_mode = MODE_ERROR;
|
||||
}
|
||||
|
||||
|
@ -91,6 +99,8 @@ void CNextion::setLockoutInt()
|
|||
|
||||
sendCommand("t0.txt=\"LOCKOUT\"");
|
||||
|
||||
m_clockDisplayTimer.stop();
|
||||
|
||||
m_mode = MODE_LOCKOUT;
|
||||
}
|
||||
|
||||
|
@ -117,6 +127,8 @@ void CNextion::writeDStarInt(const char* my1, const char* my2, const char* your,
|
|||
sendCommand(text);
|
||||
}
|
||||
|
||||
m_clockDisplayTimer.stop();
|
||||
|
||||
m_mode = MODE_DSTAR;
|
||||
}
|
||||
|
||||
|
@ -158,6 +170,8 @@ void CNextion::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro
|
|||
sendCommand(text);
|
||||
}
|
||||
|
||||
m_clockDisplayTimer.stop();
|
||||
|
||||
m_mode = MODE_DMR;
|
||||
}
|
||||
|
||||
|
@ -193,6 +207,8 @@ void CNextion::writeFusionInt(const char* source, const char* dest, const char*
|
|||
sendCommand(text);
|
||||
}
|
||||
|
||||
m_clockDisplayTimer.stop();
|
||||
|
||||
m_mode = MODE_YSF;
|
||||
}
|
||||
|
||||
|
@ -203,6 +219,35 @@ void CNextion::clearFusionInt()
|
|||
sendCommand("t2.txt=\"\"");
|
||||
}
|
||||
|
||||
void CNextion::clockInt(unsigned int ms)
|
||||
{
|
||||
// Update the clock display in IDLE mode every 400ms
|
||||
m_clockDisplayTimer.clock(ms);
|
||||
if (m_displayClock && m_mode == MODE_IDLE && m_clockDisplayTimer.isRunning() && m_clockDisplayTimer.hasExpired()) {
|
||||
time_t currentTime;
|
||||
struct tm *Time;
|
||||
::time(¤tTime); // Get the current time
|
||||
|
||||
if (m_utc)
|
||||
Time = ::gmtime(¤tTime);
|
||||
else
|
||||
Time = ::localtime(¤tTime);
|
||||
|
||||
int Day = Time->tm_mday;
|
||||
int Month = Time->tm_mon + 1;
|
||||
int Year = Time->tm_year + 1900;
|
||||
int Hour = Time->tm_hour;
|
||||
int Min = Time->tm_min;
|
||||
int Sec = Time->tm_sec;
|
||||
|
||||
char text[50U];
|
||||
::sprintf(text, "t2.txt=\"%02d:%02d:%02d %02d/%02d/%2d\"", Hour, Min, Sec, Day, Month, Year % 100);
|
||||
sendCommand(text);
|
||||
|
||||
m_clockDisplayTimer.start(); // restart the clock display timer
|
||||
}
|
||||
}
|
||||
|
||||
void CNextion::close()
|
||||
{
|
||||
m_serial.close();
|
||||
|
|
|
@ -22,13 +22,14 @@
|
|||
#include "Display.h"
|
||||
#include "Defines.h"
|
||||
#include "SerialController.h"
|
||||
#include "Timer.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
class CNextion : public CDisplay
|
||||
{
|
||||
public:
|
||||
CNextion(const std::string& callsign, unsigned int dmrid, const std::string& port, unsigned int brightness);
|
||||
CNextion(const std::string& callsign, unsigned int dmrid, const std::string& port, unsigned int brightness, bool displayClock, bool utc);
|
||||
virtual ~CNextion();
|
||||
|
||||
virtual bool open();
|
||||
|
@ -49,12 +50,17 @@ protected:
|
|||
virtual void writeFusionInt(const char* source, const char* dest, const char* type, const char* origin);
|
||||
virtual void clearFusionInt();
|
||||
|
||||
virtual void clockInt(unsigned int ms);
|
||||
|
||||
private:
|
||||
std::string m_callsign;
|
||||
unsigned int m_dmrid;
|
||||
CSerialController m_serial;
|
||||
unsigned int m_brightness;
|
||||
unsigned char m_mode;
|
||||
bool m_displayClock;
|
||||
bool m_utc;
|
||||
CTimer m_clockDisplayTimer;
|
||||
|
||||
void sendCommand(const char* command);
|
||||
};
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
101
Thread.cpp
Normal file
101
Thread.cpp
Normal file
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "Thread.h"
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
CThread::CThread() :
|
||||
m_handle()
|
||||
{
|
||||
}
|
||||
|
||||
CThread::~CThread()
|
||||
{
|
||||
}
|
||||
|
||||
bool CThread::run()
|
||||
{
|
||||
m_handle = ::CreateThread(NULL, 0, &helper, this, 0, NULL);
|
||||
|
||||
return m_handle != NULL;
|
||||
}
|
||||
|
||||
|
||||
void CThread::wait()
|
||||
{
|
||||
::WaitForSingleObject(m_handle, INFINITE);
|
||||
|
||||
::CloseHandle(m_handle);
|
||||
}
|
||||
|
||||
|
||||
DWORD CThread::helper(LPVOID arg)
|
||||
{
|
||||
CThread* p = (CThread*)arg;
|
||||
|
||||
p->entry();
|
||||
|
||||
return 0UL;
|
||||
}
|
||||
|
||||
void CThread::sleep(unsigned int ms)
|
||||
{
|
||||
::Sleep(ms);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
CThread::CThread() :
|
||||
m_thread()
|
||||
{
|
||||
}
|
||||
|
||||
CThread::~CThread()
|
||||
{
|
||||
}
|
||||
|
||||
bool CThread::run()
|
||||
{
|
||||
return ::pthread_create(&m_thread, NULL, helper, this) == 0;
|
||||
}
|
||||
|
||||
|
||||
void CThread::wait()
|
||||
{
|
||||
::pthread_join(m_thread, NULL);
|
||||
}
|
||||
|
||||
|
||||
void* CThread::helper(void* arg)
|
||||
{
|
||||
CThread* p = (CThread*)arg;
|
||||
|
||||
p->entry();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CThread::sleep(unsigned int ms)
|
||||
{
|
||||
::usleep(ms * 1000);
|
||||
}
|
||||
|
||||
#endif
|
56
Thread.h
Normal file
56
Thread.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(THREAD_H)
|
||||
#define THREAD_H
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
class CThread
|
||||
{
|
||||
public:
|
||||
CThread();
|
||||
virtual ~CThread();
|
||||
|
||||
virtual bool run();
|
||||
|
||||
virtual void entry() = 0;
|
||||
|
||||
virtual void wait();
|
||||
|
||||
static void sleep(unsigned int ms);
|
||||
|
||||
private:
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
HANDLE m_handle;
|
||||
#else
|
||||
pthread_t m_thread;
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
static DWORD __stdcall helper(LPVOID arg);
|
||||
#else
|
||||
static void* helper(void* arg);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
|
@ -459,7 +459,7 @@ void CYSFControl::writeNetwork()
|
|||
}
|
||||
|
||||
fich.setVoIP(true);
|
||||
fich.setMR(YSF_MR_NOT_BUSY);
|
||||
fich.setMR(YSF_MR_BUSY);
|
||||
fich.encode(data + 35U);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue