From 2285f9bd820ea3eb70b153de5c8340614f3e005a Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Wed, 18 Nov 2020 14:06:18 +0000 Subject: [PATCH] Initial I2C driver code. --- Config.h | 21 ++++++++++++++------- Globals.h | 8 ++++++++ I2COLED.h | 40 ++++++++++++++++++++++++++++++++++++++++ I2CPort.h | 44 ++++++++++++++++++++++++++++++++++++++++++++ IO.cpp | 4 ++++ IOSTM.cpp | 8 ++++++++ IOSTM_CMSIS.cpp | 6 ++++++ MMDVM.cpp | 6 ++++++ MMDVM.ino | 6 ++++++ SerialPort.cpp | 42 +++++++++++++++++++----------------------- SerialPort.h | 1 - 11 files changed, 155 insertions(+), 31 deletions(-) create mode 100644 I2COLED.h create mode 100644 I2CPort.h diff --git a/Config.h b/Config.h index 5568111..7547477 100644 --- a/Config.h +++ b/Config.h @@ -75,7 +75,10 @@ // #define USE_COS_AS_LOCKOUT // Use pins to output the current mode via LEDs -#define MODE_LEDS +// #define MODE_LEDS + +// Use an OLED to show the current mode via a small screen (64x32) on I2C3 +#define MODE_OLED // For the original Arduino Due pin layout // #define ARDUINO_DUE_PAPA @@ -105,10 +108,10 @@ #define SEND_RSSI_DATA // Use the modem as a serial repeater for Nextion displays -#define SERIAL_REPEATER +// #define SERIAL_REPEATER -// Use the modem as an I2C repeater for OLED displays -// #define I2C_REPEATER +// Use the modem as an I2C repeater for an OLED display on I2C1 +#define I2C_REPEATER // To reduce CPU load, you can remove the DC blocker by commenting out the next line #define USE_DCBLOCKER @@ -121,13 +124,17 @@ // #define USE_ALTERNATE_NXDN_LEDS // Use the D-Star and P25 LEDs for M17 -#define USE_ALTERNATE_M17_LEDS +// #define USE_ALTERNATE_M17_LEDS // Use the D-Star and DMR LEDs for POCSAG -#define USE_ALTERNATE_POCSAG_LEDS +// #define USE_ALTERNATE_POCSAG_LEDS // Use the D-Star and YSF LEDs for FM -#define USE_ALTERNATE_FM_LEDS +// #define USE_ALTERNATE_FM_LEDS + +#if defined(MODE_OLED) +#undef MODE_LEDS +#endif #endif diff --git a/Globals.h b/Globals.h index 797b817..32b0396 100644 --- a/Globals.h +++ b/Globals.h @@ -100,6 +100,8 @@ enum MMDVM_STATE { #include "CalNXDN.h" #include "CalPOCSAG.h" #include "CalRSSI.h" +#include "I2CPort.h" +#include "I2COLED.h" #include "CWIdTX.h" #include "AX25RX.h" #include "AX25TX.h" @@ -142,6 +144,12 @@ extern bool m_dcd; extern CSerialPort serial; extern CIO io; +#if defined(MODE_OLED) +extern CI2COLED oled; +extern CI2CPort i2C1; +extern CI2CPort i2C3; +#endif + #if defined(MODE_DSTAR) extern CDStarRX dstarRX; extern CDStarTX dstarTX; diff --git a/I2COLED.h b/I2COLED.h new file mode 100644 index 0000000..2f63e08 --- /dev/null +++ b/I2COLED.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2020 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 "Config.h" + +#if defined(MODE_OLED) + +#if !defined(I2COLED_H) +#define I2COLED_H + +#include "Globals.h" + +class CI2COLED { +public: + CI2COLED(); + + void setMode(MMDVM_STATE state); + +private: +}; + +#endif + +#endif + diff --git a/I2CPort.h b/I2CPort.h new file mode 100644 index 0000000..5fd4dd3 --- /dev/null +++ b/I2CPort.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2020 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 "Config.h" + +#if defined(MODE_OLED) || defined(I2C_REPEATER) + +#if !defined(I2CPORT_H) +#define I2CPORT_H + +#include "Globals.h" + +class CI2CPort { +public: + CI2CPort(); + + bool init(); + + uint8_t writeCommand(const uint8_t* data, uint8_t length); + + uint8_t writeData(const uint8_t* data, uint8_t length); + +private: +}; + +#endif + +#endif + diff --git a/IO.cpp b/IO.cpp index 7ad2067..5e1edcb 100644 --- a/IO.cpp +++ b/IO.cpp @@ -760,6 +760,10 @@ void CIO::setMode(MMDVM_STATE state) } #endif +#if defined(MODE_OLED) + oled.setMode(state); +#endif + m_modemState = state; } diff --git a/IOSTM.cpp b/IOSTM.cpp index db87da0..f5b13ea 100644 --- a/IOSTM.cpp +++ b/IOSTM.cpp @@ -190,6 +190,14 @@ void CIO::initInt() #endif #endif + +#if defined(MODE_OLED) + I2C3Init(); +#endif + +#if defined(I2C_REPEATER) + I2C1Init(); +#endif } void CIO::startInt() diff --git a/IOSTM_CMSIS.cpp b/IOSTM_CMSIS.cpp index 300a88a..2a0baa9 100644 --- a/IOSTM_CMSIS.cpp +++ b/IOSTM_CMSIS.cpp @@ -357,6 +357,12 @@ void CIO::initInt() #if defined(STM32F1_POG) FancyLEDEffect(); #endif +#if defined(MODE_OLED) + I2C3Init(); +#endif +#if defined(I2C_REPEATER) + I2C1Init(); +#endif } void CIO::startInt() diff --git a/MMDVM.cpp b/MMDVM.cpp index f1cec7e..c023828 100644 --- a/MMDVM.cpp +++ b/MMDVM.cpp @@ -41,6 +41,12 @@ bool m_duplex = true; bool m_tx = false; bool m_dcd = false; +#if defined(MODE_OLED) +CI2COLED oled; +CI2CPort i2C1; +CI2CPort i2C3; +#endif + #if defined(MODE_DSTAR) CDStarRX dstarRX; CDStarTX dstarTX; diff --git a/MMDVM.ino b/MMDVM.ino index ac125d5..7b049a6 100644 --- a/MMDVM.ino +++ b/MMDVM.ino @@ -38,6 +38,12 @@ bool m_duplex = true; bool m_tx = false; bool m_dcd = false; +#if defined(MODE_OLED) +CI2COLED oled; +CI2CPort i2C1; +CI2CPort i2C3; +#endif + #if defined(MODE_DSTAR) CDStarRX dstarRX; CDStarTX dstarTX; diff --git a/SerialPort.cpp b/SerialPort.cpp index aa0f54e..a2a75f3 100644 --- a/SerialPort.cpp +++ b/SerialPort.cpp @@ -127,6 +127,10 @@ const uint8_t PROTOCOL_VERSION = 2U; const int MAX_SERIAL_DATA = 250; const uint16_t MAX_SERIAL_COUNT = 100U; +// I2C types +const uint8_t I2C_COMMAND = 0x00U; +const uint8_t I2C_DATA = 0x40U; + CSerialPort::CSerialPort() : m_buffer(), m_ptr(0U), @@ -134,8 +138,7 @@ m_len(0U), m_debug(false), m_serialData(), m_lastSerialAvail(0), -m_lastSerialAvailCount(0U), -m_i2CData() +m_lastSerialAvailCount(0U) { } @@ -852,9 +855,6 @@ void CSerialPort::start() #if defined(SERIAL_REPEATER) beginInt(3U, 9600); #endif -#if defined(I2C_REPEATER) - beginInt(10U, 9600); -#endif } void CSerialPort::process() @@ -939,22 +939,6 @@ void CSerialPort::process() m_lastSerialAvailCount = 0U; } #endif - -#if defined(I2C_REPEATER) - // Write any outgoing serial data - uint16_t i2CSpace = m_i2CData.getData(); - if (i2CSpace > 0U) { - int avail = availableForWriteInt(10U); - if (avail < i2CSpace) - i2CSpace = avail; - - for (uint16_t i = 0U; i < i2CSpace; i++) { - uint8_t c = 0U; - m_i2CData.get(c); - writeInt(10U, &c, 1U); - } - } -#endif } void CSerialPort::processMessage(uint8_t type, const uint8_t* buffer, uint16_t length) @@ -1332,8 +1316,20 @@ void CSerialPort::processMessage(uint8_t type, const uint8_t* buffer, uint16_t l #if defined(I2C_REPEATER) case MMDVM_I2C_DATA: { - for (uint16_t i = 0U; i < length; i++) - m_i2CData.put(buffer[i]); + uint8_t type = buffer[0U]; + uint8_t err = 4U; + switch (type) { + case I2C_COMMAND: + err = i2C1.writeCommand(buffer + 1U, length - 1U); + break; + case I2C_DATA: + err = i2C1.writeData(buffer + 1U, length - 1U); + break; + } + if (err != 0U) { + DEBUG2("Received invalid I2C data", err); + sendNAK(err); + } } break; #endif diff --git a/SerialPort.h b/SerialPort.h index 8b7541b..f539316 100644 --- a/SerialPort.h +++ b/SerialPort.h @@ -100,7 +100,6 @@ private: CRingBuffer m_serialData; int m_lastSerialAvail; uint16_t m_lastSerialAvailCount; - CRingBuffer m_i2CData; void sendACK(); void sendNAK(uint8_t err);