mirror of
https://github.com/g4klx/MMDVM.git
synced 2026-08-21 14:36:21 +02:00
Compare commits
46
Commits
3fd84d5ed4
...
I2C
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
73866ab591 | ||
|
|
ed84db6ee4 | ||
|
|
406a60d787 | ||
|
|
f06774aadd | ||
|
|
e32f13d3df | ||
|
|
7db7bbb02e | ||
|
|
794acf1df8 | ||
|
|
02ba20401b | ||
|
|
ee3ab88b2a | ||
|
|
a5d4295cce | ||
|
|
1e97e7c2a0 | ||
|
|
246539526d | ||
|
|
3c6a1f262a | ||
|
|
51b275d4c7 | ||
|
|
639caa03ee | ||
|
|
4f3e6935d2 | ||
|
|
a3e0ad82e2 | ||
|
|
4aa30664b9 | ||
|
|
c83879d89d | ||
|
|
683c5afccb | ||
|
|
c70540a8ac | ||
|
|
93115c8931 | ||
|
|
2ae731e78c | ||
|
|
f033fea2fb | ||
|
|
4539f48af2 | ||
|
|
8747794e27 | ||
|
|
e94f5bb13a | ||
|
|
28a0910638 | ||
|
|
2dd8b74346 | ||
|
|
2190dc1042 | ||
|
|
9b76867548 | ||
|
|
df749d3286 | ||
|
|
5e8e0577da | ||
|
|
6c8cf7a838 | ||
|
|
112a136060 | ||
|
|
b4ff147a19 | ||
|
|
757c3ce0d5 | ||
|
|
a119311d93 | ||
|
|
7f7ce2072a | ||
|
|
1978b2b357 | ||
|
|
6f1fe8d4b9 | ||
|
|
f0804b46e5 | ||
|
|
2285f9bd82 | ||
|
|
53b5659639 | ||
|
|
864dfa9221 | ||
|
|
335c32c540 |
+3
-3
@@ -1,9 +1,9 @@
|
||||
[submodule "STM32F4XX_Lib"]
|
||||
path = STM32F4XX_Lib
|
||||
url = https://github.com/juribeparada/STM32F4XX_Lib.git
|
||||
[submodule "STM32F7XX_Lib"]
|
||||
path = STM32F7XX_Lib
|
||||
url = https://github.com/juribeparada/STM32F7XX_Lib.git
|
||||
[submodule "STM32F10X_Lib"]
|
||||
path = STM32F10X_Lib
|
||||
url = https://github.com/shawnchain/STM32F10X_Lib.git
|
||||
[submodule "STM32F7XX_Lib"]
|
||||
path = STM32F7XX_Lib
|
||||
url = https://github.com/g4klx/STM32F7XX_Lib.git
|
||||
|
||||
@@ -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,7 @@
|
||||
#define SEND_RSSI_DATA
|
||||
|
||||
// Use the modem as a serial repeater for Nextion displays
|
||||
#define SERIAL_REPEATER
|
||||
|
||||
// Use the modem as an I2C repeater for OLED displays
|
||||
// #define I2C_REPEATER
|
||||
// #define SERIAL_REPEATER
|
||||
|
||||
// To reduce CPU load, you can remove the DC blocker by commenting out the next line
|
||||
#define USE_DCBLOCKER
|
||||
@@ -121,13 +121,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
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2017,2018,2020,2021 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
|
||||
@@ -100,10 +100,12 @@ enum MMDVM_STATE {
|
||||
#include "CalNXDN.h"
|
||||
#include "CalPOCSAG.h"
|
||||
#include "CalRSSI.h"
|
||||
#include "I2COLED.h"
|
||||
#include "CWIdTX.h"
|
||||
#include "AX25RX.h"
|
||||
#include "AX25TX.h"
|
||||
#include "Debug.h"
|
||||
#include "I2C3.h"
|
||||
#include "IO.h"
|
||||
#include "FM.h"
|
||||
|
||||
@@ -142,6 +144,10 @@ extern bool m_dcd;
|
||||
extern CSerialPort serial;
|
||||
extern CIO io;
|
||||
|
||||
#if defined(MODE_OLED)
|
||||
extern CI2COLED oled;
|
||||
#endif
|
||||
|
||||
#if defined(MODE_DSTAR)
|
||||
extern CDStarRX dstarRX;
|
||||
extern CDStarTX dstarTX;
|
||||
|
||||
@@ -0,0 +1,284 @@
|
||||
/*
|
||||
* Copyright (C) 2020,2021 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)
|
||||
|
||||
#include "I2C3.h"
|
||||
|
||||
#include "Globals.h"
|
||||
|
||||
|
||||
#define I2C_WRITE_REG(REG, VAL) ((REG) = (VAL))
|
||||
#define I2C_READ_REG(REG) ((REG))
|
||||
|
||||
#define I2C_CLEAR_FLAG(__FLAG__) (((__FLAG__) == I2C_FLAG_TXE) ? (I2C3->ISR |= (__FLAG__)) : (I2C3->ICR = (__FLAG__)))
|
||||
#define I2C_GET_FLAG(__FLAG__) ((((I2C3->ISR) & (__FLAG__)) == (__FLAG__)) ? SET : RESET)
|
||||
|
||||
#define I2C_RESET_CR2() (I2C3->CR2 &= (uint32_t)~((uint32_t)(I2C_CR2_SADD | I2C_CR2_HEAD10R | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_RD_WRN)))
|
||||
|
||||
#define I2C_MODIFY_REG(REG, CLEARMASK, SETMASK) I2C_WRITE_REG((REG), (((I2C_READ_REG(REG)) & (~(CLEARMASK))) | (SETMASK)))
|
||||
|
||||
#define TIMING_CLEAR_MASK (0xF0FFFFFFU)
|
||||
|
||||
#define I2C_DUALADDRESS_DISABLE (0x00000000U)
|
||||
#define I2C_DUALADDRESS_ENABLE I2C_OAR2_OA2EN
|
||||
|
||||
#define I2C_GENERALCALL_DISABLE (0x00000000U)
|
||||
|
||||
#define I2C_NOSTRETCH_DISABLE (0x00000000U)
|
||||
|
||||
#define I2C_ANALOGFILTER_ENABLE 0x00000000U
|
||||
|
||||
#define RCC_I2C3CLKSOURCE_PCLK1 ((uint32_t)0x00000000U)
|
||||
|
||||
#define I2C_OA2_NOMASK ((uint8_t)0x00U)
|
||||
|
||||
#define GPIO_MODE_AF_OD ((uint32_t)0x00000012U)
|
||||
|
||||
#define GPIO_OUTPUT_TYPE ((uint32_t)0x00000010U)
|
||||
|
||||
#define GPIO_MODE ((uint32_t)0x00000003U)
|
||||
|
||||
#define GPIO_NUMBER (16U)
|
||||
|
||||
#define I2C_ENABLE() (SET_BIT(I2C3->CR1, I2C_CR1_PE))
|
||||
|
||||
#define I2C_DISABLE() (CLEAR_BIT(I2C3->CR1, I2C_CR1_PE))
|
||||
|
||||
#define RCC_GPIOA_CLK_ENABLE() do { \
|
||||
__IO uint32_t tmpreg; \
|
||||
SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);\
|
||||
tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOAEN);\
|
||||
} while(0)
|
||||
|
||||
#define RCC_GPIOC_CLK_ENABLE() do { \
|
||||
__IO uint32_t tmpreg; \
|
||||
SET_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);\
|
||||
tmpreg = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);\
|
||||
} while(0)
|
||||
|
||||
#define RCC_I2C3_CLK_ENABLE() do { \
|
||||
__IO uint32_t tmpreg; \
|
||||
SET_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C3EN);\
|
||||
tmpreg = READ_BIT(RCC->APB1ENR, RCC_APB1ENR_I2C3EN);\
|
||||
} while(0)
|
||||
|
||||
CI2C3::CI2C3()
|
||||
{
|
||||
}
|
||||
|
||||
void CI2C3::init()
|
||||
{
|
||||
// Enable the I2C3 clock
|
||||
I2C_MODIFY_REG(RCC->DCKCFGR2, RCC_DCKCFGR2_I2C3SEL, RCC_I2C3CLKSOURCE_PCLK1);
|
||||
|
||||
// Enable the GPIOs for the SCL/SDA Pins
|
||||
RCC_GPIOC_CLK_ENABLE();
|
||||
RCC_GPIOA_CLK_ENABLE();
|
||||
|
||||
initI2C3();
|
||||
|
||||
// Configure Analogue filter
|
||||
configAnalogFilter(I2C_ANALOGFILTER_ENABLE);
|
||||
|
||||
// Configure Digital filter
|
||||
configDigitalFilter(0U);
|
||||
}
|
||||
|
||||
void CI2C3::write(uint16_t addr, const uint8_t* data, uint8_t length)
|
||||
{
|
||||
DEBUG2("OLED Data", addr);
|
||||
DEBUG_DUMP(data, length);
|
||||
|
||||
// Shift the address to the left
|
||||
addr <<= 3;
|
||||
|
||||
// Wait for the I2C transmitter to become free
|
||||
while (I2C_GET_FLAG(I2C_FLAG_BUSY) == SET)
|
||||
;
|
||||
|
||||
// Configure the data transfer
|
||||
transferConfig(addr, length, I2C_CR2_AUTOEND, I2C_Generate_Start_Write);
|
||||
|
||||
// Start Writing Data
|
||||
for (uint16_t i = 0U; i < length; i++) {
|
||||
// Wait for the TXIS flag to be set
|
||||
while (I2C_GET_FLAG(I2C_FLAG_TXIS) == RESET)
|
||||
;
|
||||
|
||||
// Write the byte to the TXDR
|
||||
I2C3->TXDR = data[i];
|
||||
}
|
||||
|
||||
// No need to Check TC flag, with AUTOEND mode the stop is automatically generated Wait until STOPF flag is set
|
||||
while (I2C_GET_FLAG(I2C_FLAG_STOPF) == RESET)
|
||||
;
|
||||
|
||||
// Clear STOP flag
|
||||
I2C_CLEAR_FLAG(I2C_FLAG_STOPF);
|
||||
|
||||
// Clear Configuration Register 2
|
||||
I2C_RESET_CR2();
|
||||
}
|
||||
|
||||
void CI2C3::transferConfig(uint16_t addr, uint8_t length, uint32_t mode, uint32_t request)
|
||||
{
|
||||
// Update CR2 register
|
||||
I2C_MODIFY_REG(I2C3->CR2, ((I2C_CR2_SADD | I2C_CR2_NBYTES | I2C_CR2_RELOAD | I2C_CR2_AUTOEND | \
|
||||
(I2C_CR2_RD_WRN & (uint32_t)(request >> (31U - I2C_CR2_RD_WRN_Pos))) | I2C_CR2_START | I2C_CR2_STOP)), \
|
||||
(uint32_t)(((uint32_t)addr & I2C_CR2_SADD) |
|
||||
(((uint32_t)length << I2C_CR2_NBYTES_Pos) & I2C_CR2_NBYTES) | (uint32_t)mode | (uint32_t)request));
|
||||
}
|
||||
|
||||
void CI2C3::configAnalogFilter(uint32_t AnalogFilter)
|
||||
{
|
||||
// Disable the selected I2C peripheral
|
||||
I2C_DISABLE();
|
||||
|
||||
// Reset I2Cx ANOFF bit
|
||||
I2C3->CR1 &= ~(I2C_CR1_ANFOFF);
|
||||
|
||||
// Set analog filter bit
|
||||
I2C3->CR1 |= AnalogFilter;
|
||||
|
||||
I2C_ENABLE();
|
||||
}
|
||||
|
||||
void CI2C3::configDigitalFilter(uint32_t DigitalFilter)
|
||||
{
|
||||
// Disable the selected I2C peripheral
|
||||
I2C_DISABLE();
|
||||
|
||||
// Get the old register value
|
||||
uint32_t tmpreg = I2C3->CR1;
|
||||
|
||||
// Reset I2Cx DNF bits [11:8]
|
||||
tmpreg &= ~(I2C_CR1_DNF);
|
||||
|
||||
// Set I2Cx DNF coefficient
|
||||
tmpreg |= DigitalFilter << 8U;
|
||||
|
||||
// Store the new register value
|
||||
I2C3->CR1 = tmpreg;
|
||||
|
||||
I2C_ENABLE();
|
||||
}
|
||||
|
||||
void CI2C3::initI2C3()
|
||||
{
|
||||
initMSP();
|
||||
|
||||
/* Disable the selected I2C peripheral */
|
||||
I2C_DISABLE();
|
||||
|
||||
/*---------------------------- I2Cx TIMINGR Configuration ------------------*/
|
||||
/* Configure I2Cx: Frequency range */
|
||||
I2C3->TIMINGR = 0x0010061AU & TIMING_CLEAR_MASK;
|
||||
|
||||
/*---------------------------- I2Cx OAR1 Configuration ---------------------*/
|
||||
/* Disable Own Address1 before set the Own Address1 configuration */
|
||||
I2C3->OAR1 &= ~I2C_OAR1_OA1EN;
|
||||
|
||||
/* Configure I2Cx: Own Address1 and ack own address1 mode */
|
||||
I2C3->OAR1 = (I2C_OAR1_OA1EN | 0U);
|
||||
|
||||
/*---------------------------- I2Cx CR2 Configuration ----------------------*/
|
||||
/* Enable the AUTOEND by default, and enable NACK (should be disable only during Slave process */
|
||||
I2C3->CR2 |= (I2C_CR2_AUTOEND | I2C_CR2_NACK);
|
||||
|
||||
/*---------------------------- I2Cx OAR2 Configuration ---------------------*/
|
||||
/* Disable Own Address2 before set the Own Address2 configuration */
|
||||
I2C3->OAR2 &= ~I2C_DUALADDRESS_ENABLE;
|
||||
|
||||
/* Configure I2Cx: Dual mode and Own Address2 */
|
||||
I2C3->OAR2 = (I2C_DUALADDRESS_DISABLE | 0U | (I2C_OA2_NOMASK << 8));
|
||||
|
||||
/*---------------------------- I2Cx CR1 Configuration ----------------------*/
|
||||
/* Configure I2Cx: Generalcall and NoStretch mode */
|
||||
I2C3->CR1 = (I2C_GENERALCALL_DISABLE | I2C_NOSTRETCH_DISABLE);
|
||||
|
||||
/* Enable the selected I2C peripheral */
|
||||
I2C_ENABLE();
|
||||
}
|
||||
|
||||
void CI2C3::initMSP()
|
||||
{
|
||||
RCC_GPIOC_CLK_ENABLE();
|
||||
RCC_GPIOA_CLK_ENABLE();
|
||||
|
||||
/* I2C3 GPIO Configuration
|
||||
PC9 ------> I2C3_SDA
|
||||
PA8 ------> I2C3_SCL
|
||||
*/
|
||||
initGPIO(GPIOC, GPIO_Pin_9);
|
||||
initGPIO(GPIOA, GPIO_Pin_8);
|
||||
|
||||
// Peripheral clock enable
|
||||
RCC_I2C3_CLK_ENABLE();
|
||||
}
|
||||
|
||||
void CI2C3::initGPIO(GPIO_TypeDef* GPIOx, uint32_t Pin)
|
||||
{
|
||||
// Configure the port pins
|
||||
for (uint32_t position = 0U; position < GPIO_NUMBER; position++)
|
||||
{
|
||||
// Get the IO position
|
||||
uint32_t ioposition = ((uint32_t)0x01) << position;
|
||||
|
||||
// Get the current IO position
|
||||
uint32_t iocurrent = Pin & ioposition;
|
||||
|
||||
if (iocurrent == ioposition)
|
||||
{
|
||||
// Configure the IO Speed
|
||||
uint32_t temp = GPIOx->OSPEEDR;
|
||||
temp &= ~(GPIO_OSPEEDER_OSPEEDR0 << (position * 2));
|
||||
temp |= (GPIO_High_Speed << (position * 2));
|
||||
GPIOx->OSPEEDR = temp;
|
||||
|
||||
// Configure the IO Output Type
|
||||
temp = GPIOx->OTYPER;
|
||||
temp &= ~(GPIO_OTYPER_OT_0 << position) ;
|
||||
temp |= (((GPIO_MODE_AF_OD & GPIO_OUTPUT_TYPE) >> 4) << position);
|
||||
GPIOx->OTYPER = temp;
|
||||
|
||||
// Activate the Pull Up resistor for the current IO
|
||||
temp = GPIOx->PUPDR;
|
||||
temp &= ~(GPIO_PUPDR_PUPDR0 << (position * 2));
|
||||
temp |= ((GPIO_PuPd_UP) << (position * 2));
|
||||
GPIOx->PUPDR = temp;
|
||||
|
||||
// Configure Alternate function mapped with the current IO
|
||||
temp = GPIOx->AFR[position >> 3];
|
||||
temp &= ~((uint32_t)0xF << ((uint32_t)(position & (uint32_t)0x07) * 4)) ;
|
||||
temp |= ((uint32_t)(GPIO_AF4_I2C3) << (((uint32_t)position & (uint32_t)0x07) * 4));
|
||||
GPIOx->AFR[position >> 3] = temp;
|
||||
|
||||
// Configure IO Direction mode (Input, Output, Alternate or Analog)
|
||||
temp = GPIOx->MODER;
|
||||
temp &= ~(GPIO_MODER_MODER0 << (position * 2));
|
||||
temp |= ((GPIO_MODE_AF_OD & GPIO_MODE) << (position * 2));
|
||||
GPIOx->MODER = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2020,2021 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(I2C3_H)
|
||||
#define I2C3_H
|
||||
|
||||
#if defined(STM32F7XX)
|
||||
#include "stm32f7xx.h"
|
||||
#include "stm32f7xx_i2c.h"
|
||||
#endif
|
||||
|
||||
|
||||
class CI2C3 {
|
||||
public:
|
||||
CI2C3();
|
||||
|
||||
void init();
|
||||
|
||||
void write(uint16_t addr, const uint8_t* data, uint8_t length);
|
||||
|
||||
private:
|
||||
void transferConfig(uint16_t addr, uint8_t length, uint32_t mode, uint32_t request);
|
||||
void configAnalogFilter(uint32_t AnalogFilter);
|
||||
void configDigitalFilter(uint32_t DigitalFilter);
|
||||
void initI2C3();
|
||||
void initMSP();
|
||||
void initGPIO(GPIO_TypeDef* GPIOx, uint32_t Pin);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
+509
@@ -0,0 +1,509 @@
|
||||
/*
|
||||
* Copyright (C) 2020,2021 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)
|
||||
|
||||
#include "I2COLED.h"
|
||||
#include "I2C3.h"
|
||||
|
||||
#include "Globals.h"
|
||||
|
||||
const uint8_t OLED_ADDRESS = 0x78U;
|
||||
|
||||
const uint8_t OLED_WIDTH = 64U;
|
||||
const uint8_t OLED_HEIGHT = 32U;
|
||||
const uint16_t OLED_BUFFER_SIZE = (OLED_HEIGHT * OLED_WIDTH) / 8U;
|
||||
|
||||
const uint8_t SSD_Command_Mode = 0x00U; /* C0 and DC bit are 0 */
|
||||
const uint8_t SSD_Data_Mode = 0x40U; /* C0 bit is 0 and DC bit is 1 */
|
||||
|
||||
const uint8_t SSD1306_Set_Lower_Column_Start_Address = 0x00U;
|
||||
const uint8_t SSD1306_Set_Higher_Column_Start_Address = 0x10U;
|
||||
const uint8_t SSD1306_Set_Start_Line = 0x40U;
|
||||
|
||||
const uint8_t CHAR_HEIGHT = 5U;
|
||||
const uint8_t CHAR_WIDTH = 7U;
|
||||
|
||||
// Standard ascii 5x7 font
|
||||
const uint8_t FONT[] = {
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
0x3EU, 0x5BU, 0x4FU, 0x5BU, 0x3EU,
|
||||
0x3EU, 0x6BU, 0x4FU, 0x6BU, 0x3EU,
|
||||
0x1CU, 0x3EU, 0x7CU, 0x3EU, 0x1CU,
|
||||
0x18U, 0x3CU, 0x7EU, 0x3CU, 0x18U,
|
||||
0x1CU, 0x57U, 0x7DU, 0x57U, 0x1CU,
|
||||
0x1CU, 0x5EU, 0x7FU, 0x5EU, 0x1CU,
|
||||
0x00U, 0x18U, 0x3CU, 0x18U, 0x00U,
|
||||
0xFFU, 0xE7U, 0xC3U, 0xE7U, 0xFFU,
|
||||
0x00U, 0x18U, 0x24U, 0x18U, 0x00U,
|
||||
0xFFU, 0xE7U, 0xDBU, 0xE7U, 0xFFU,
|
||||
0x30U, 0x48U, 0x3AU, 0x06U, 0x0EU,
|
||||
0x26U, 0x29U, 0x79U, 0x29U, 0x26U,
|
||||
0x40U, 0x7FU, 0x05U, 0x05U, 0x07U,
|
||||
0x40U, 0x7FU, 0x05U, 0x25U, 0x3FU,
|
||||
0x5AU, 0x3CU, 0xE7U, 0x3CU, 0x5AU,
|
||||
0x7FU, 0x3EU, 0x1CU, 0x1CU, 0x08U,
|
||||
0x08U, 0x1CU, 0x1CU, 0x3EU, 0x7FU,
|
||||
0x14U, 0x22U, 0x7FU, 0x22U, 0x14U,
|
||||
0x5FU, 0x5FU, 0x00U, 0x5FU, 0x5FU,
|
||||
0x06U, 0x09U, 0x7FU, 0x01U, 0x7FU,
|
||||
0x00U, 0x66U, 0x89U, 0x95U, 0x6AU,
|
||||
0x60U, 0x60U, 0x60U, 0x60U, 0x60U,
|
||||
0x94U, 0xA2U, 0xFFU, 0xA2U, 0x94U,
|
||||
0x08U, 0x04U, 0x7EU, 0x04U, 0x08U,
|
||||
0x10U, 0x20U, 0x7EU, 0x20U, 0x10U,
|
||||
0x08U, 0x08U, 0x2AU, 0x1CU, 0x08U,
|
||||
0x08U, 0x1CU, 0x2AU, 0x08U, 0x08U,
|
||||
0x1EU, 0x10U, 0x10U, 0x10U, 0x10U,
|
||||
0x0CU, 0x1EU, 0x0CU, 0x1EU, 0x0CU,
|
||||
0x30U, 0x38U, 0x3EU, 0x38U, 0x30U,
|
||||
0x06U, 0x0EU, 0x3EU, 0x0EU, 0x06U,
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 0x00U,
|
||||
0x00U, 0x00U, 0x5FU, 0x00U, 0x00U,
|
||||
0x00U, 0x07U, 0x00U, 0x07U, 0x00U,
|
||||
0x14U, 0x7FU, 0x14U, 0x7FU, 0x14U,
|
||||
0x24U, 0x2AU, 0x7FU, 0x2AU, 0x12U,
|
||||
0x23U, 0x13U, 0x08U, 0x64U, 0x62U,
|
||||
0x36U, 0x49U, 0x56U, 0x20U, 0x50U,
|
||||
0x00U, 0x08U, 0x07U, 0x03U, 0x00U,
|
||||
0x00U, 0x1CU, 0x22U, 0x41U, 0x00U,
|
||||
0x00U, 0x41U, 0x22U, 0x1CU, 0x00U,
|
||||
0x2AU, 0x1CU, 0x7FU, 0x1CU, 0x2AU,
|
||||
0x08U, 0x08U, 0x3EU, 0x08U, 0x08U,
|
||||
0x00U, 0x80U, 0x70U, 0x30U, 0x00U,
|
||||
0x08U, 0x08U, 0x08U, 0x08U, 0x08U,
|
||||
0x00U, 0x00U, 0x60U, 0x60U, 0x00U,
|
||||
0x20U, 0x10U, 0x08U, 0x04U, 0x02U,
|
||||
0x3EU, 0x51U, 0x49U, 0x45U, 0x3EU,
|
||||
0x00U, 0x42U, 0x7FU, 0x40U, 0x00U,
|
||||
0x72U, 0x49U, 0x49U, 0x49U, 0x46U,
|
||||
0x21U, 0x41U, 0x49U, 0x4DU, 0x33U,
|
||||
0x18U, 0x14U, 0x12U, 0x7FU, 0x10U,
|
||||
0x27U, 0x45U, 0x45U, 0x45U, 0x39U,
|
||||
0x3CU, 0x4AU, 0x49U, 0x49U, 0x31U,
|
||||
0x41U, 0x21U, 0x11U, 0x09U, 0x07U,
|
||||
0x36U, 0x49U, 0x49U, 0x49U, 0x36U,
|
||||
0x46U, 0x49U, 0x49U, 0x29U, 0x1EU,
|
||||
0x00U, 0x00U, 0x14U, 0x00U, 0x00U,
|
||||
0x00U, 0x40U, 0x34U, 0x00U, 0x00U,
|
||||
0x00U, 0x08U, 0x14U, 0x22U, 0x41U,
|
||||
0x14U, 0x14U, 0x14U, 0x14U, 0x14U,
|
||||
0x00U, 0x41U, 0x22U, 0x14U, 0x08U,
|
||||
0x02U, 0x01U, 0x59U, 0x09U, 0x06U,
|
||||
0x3EU, 0x41U, 0x5DU, 0x59U, 0x4EU,
|
||||
0x7CU, 0x12U, 0x11U, 0x12U, 0x7CU,
|
||||
0x7FU, 0x49U, 0x49U, 0x49U, 0x36U,
|
||||
0x3EU, 0x41U, 0x41U, 0x41U, 0x22U,
|
||||
0x7FU, 0x41U, 0x41U, 0x41U, 0x3EU,
|
||||
0x7FU, 0x49U, 0x49U, 0x49U, 0x41U,
|
||||
0x7FU, 0x09U, 0x09U, 0x09U, 0x01U,
|
||||
0x3EU, 0x41U, 0x41U, 0x51U, 0x73U,
|
||||
0x7FU, 0x08U, 0x08U, 0x08U, 0x7FU,
|
||||
0x00U, 0x41U, 0x7FU, 0x41U, 0x00U,
|
||||
0x20U, 0x40U, 0x41U, 0x3FU, 0x01U,
|
||||
0x7FU, 0x08U, 0x14U, 0x22U, 0x41U,
|
||||
0x7FU, 0x40U, 0x40U, 0x40U, 0x40U,
|
||||
0x7FU, 0x02U, 0x1CU, 0x02U, 0x7FU,
|
||||
0x7FU, 0x04U, 0x08U, 0x10U, 0x7FU,
|
||||
0x3EU, 0x41U, 0x41U, 0x41U, 0x3EU,
|
||||
0x7FU, 0x09U, 0x09U, 0x09U, 0x06U,
|
||||
0x3EU, 0x41U, 0x51U, 0x21U, 0x5EU,
|
||||
0x7FU, 0x09U, 0x19U, 0x29U, 0x46U,
|
||||
0x26U, 0x49U, 0x49U, 0x49U, 0x32U,
|
||||
0x03U, 0x01U, 0x7FU, 0x01U, 0x03U,
|
||||
0x3FU, 0x40U, 0x40U, 0x40U, 0x3FU,
|
||||
0x1FU, 0x20U, 0x40U, 0x20U, 0x1FU,
|
||||
0x3FU, 0x40U, 0x38U, 0x40U, 0x3FU,
|
||||
0x63U, 0x14U, 0x08U, 0x14U, 0x63U,
|
||||
0x03U, 0x04U, 0x78U, 0x04U, 0x03U,
|
||||
0x61U, 0x59U, 0x49U, 0x4DU, 0x43U,
|
||||
0x00U, 0x7FU, 0x41U, 0x41U, 0x41U,
|
||||
0x02U, 0x04U, 0x08U, 0x10U, 0x20U,
|
||||
0x00U, 0x41U, 0x41U, 0x41U, 0x7FU,
|
||||
0x04U, 0x02U, 0x01U, 0x02U, 0x04U,
|
||||
0x40U, 0x40U, 0x40U, 0x40U, 0x40U,
|
||||
0x00U, 0x03U, 0x07U, 0x08U, 0x00U,
|
||||
0x20U, 0x54U, 0x54U, 0x78U, 0x40U,
|
||||
0x7FU, 0x28U, 0x44U, 0x44U, 0x38U,
|
||||
0x38U, 0x44U, 0x44U, 0x44U, 0x28U,
|
||||
0x38U, 0x44U, 0x44U, 0x28U, 0x7FU,
|
||||
0x38U, 0x54U, 0x54U, 0x54U, 0x18U,
|
||||
0x00U, 0x08U, 0x7EU, 0x09U, 0x02U,
|
||||
0x18U, 0xA4U, 0xA4U, 0x9CU, 0x78U,
|
||||
0x7FU, 0x08U, 0x04U, 0x04U, 0x78U,
|
||||
0x00U, 0x44U, 0x7DU, 0x40U, 0x00U,
|
||||
0x20U, 0x40U, 0x40U, 0x3DU, 0x00U,
|
||||
0x7FU, 0x10U, 0x28U, 0x44U, 0x00U,
|
||||
0x00U, 0x41U, 0x7FU, 0x40U, 0x00U,
|
||||
0x7CU, 0x04U, 0x78U, 0x04U, 0x78U,
|
||||
0x7CU, 0x08U, 0x04U, 0x04U, 0x78U,
|
||||
0x38U, 0x44U, 0x44U, 0x44U, 0x38U,
|
||||
0xFCU, 0x18U, 0x24U, 0x24U, 0x18U,
|
||||
0x18U, 0x24U, 0x24U, 0x18U, 0xFCU,
|
||||
0x7CU, 0x08U, 0x04U, 0x04U, 0x08U,
|
||||
0x48U, 0x54U, 0x54U, 0x54U, 0x24U,
|
||||
0x04U, 0x04U, 0x3FU, 0x44U, 0x24U,
|
||||
0x3CU, 0x40U, 0x40U, 0x20U, 0x7CU,
|
||||
0x1CU, 0x20U, 0x40U, 0x20U, 0x1CU,
|
||||
0x3CU, 0x40U, 0x30U, 0x40U, 0x3CU,
|
||||
0x44U, 0x28U, 0x10U, 0x28U, 0x44U,
|
||||
0x4CU, 0x90U, 0x90U, 0x90U, 0x7CU,
|
||||
0x44U, 0x64U, 0x54U, 0x4CU, 0x44U,
|
||||
0x00U, 0x08U, 0x36U, 0x41U, 0x00U,
|
||||
0x00U, 0x00U, 0x77U, 0x00U, 0x00U,
|
||||
0x00U, 0x41U, 0x36U, 0x08U, 0x00U,
|
||||
0x02U, 0x01U, 0x02U, 0x04U, 0x02U,
|
||||
0x3CU, 0x26U, 0x23U, 0x26U, 0x3CU,
|
||||
0x1EU, 0xA1U, 0xA1U, 0x61U, 0x12U,
|
||||
0x3AU, 0x40U, 0x40U, 0x20U, 0x7AU,
|
||||
0x38U, 0x54U, 0x54U, 0x55U, 0x59U,
|
||||
0x21U, 0x55U, 0x55U, 0x79U, 0x41U,
|
||||
0x21U, 0x54U, 0x54U, 0x78U, 0x41U,
|
||||
0x21U, 0x55U, 0x54U, 0x78U, 0x40U,
|
||||
0x20U, 0x54U, 0x55U, 0x79U, 0x40U,
|
||||
0x0CU, 0x1EU, 0x52U, 0x72U, 0x12U,
|
||||
0x39U, 0x55U, 0x55U, 0x55U, 0x59U,
|
||||
0x39U, 0x54U, 0x54U, 0x54U, 0x59U,
|
||||
0x39U, 0x55U, 0x54U, 0x54U, 0x58U,
|
||||
0x00U, 0x00U, 0x45U, 0x7CU, 0x41U,
|
||||
0x00U, 0x02U, 0x45U, 0x7DU, 0x42U,
|
||||
0x00U, 0x01U, 0x45U, 0x7CU, 0x40U,
|
||||
0xF0U, 0x29U, 0x24U, 0x29U, 0xF0U,
|
||||
0xF0U, 0x28U, 0x25U, 0x28U, 0xF0U,
|
||||
0x7CU, 0x54U, 0x55U, 0x45U, 0x00U,
|
||||
0x20U, 0x54U, 0x54U, 0x7CU, 0x54U,
|
||||
0x7CU, 0x0AU, 0x09U, 0x7FU, 0x49U,
|
||||
0x32U, 0x49U, 0x49U, 0x49U, 0x32U,
|
||||
0x32U, 0x48U, 0x48U, 0x48U, 0x32U,
|
||||
0x32U, 0x4AU, 0x48U, 0x48U, 0x30U,
|
||||
0x3AU, 0x41U, 0x41U, 0x21U, 0x7AU,
|
||||
0x3AU, 0x42U, 0x40U, 0x20U, 0x78U,
|
||||
0x00U, 0x9DU, 0xA0U, 0xA0U, 0x7DU,
|
||||
0x39U, 0x44U, 0x44U, 0x44U, 0x39U,
|
||||
0x3DU, 0x40U, 0x40U, 0x40U, 0x3DU,
|
||||
0x3CU, 0x24U, 0xFFU, 0x24U, 0x24U,
|
||||
0x48U, 0x7EU, 0x49U, 0x43U, 0x66U,
|
||||
0x2BU, 0x2FU, 0xFCU, 0x2FU, 0x2BU,
|
||||
0xFFU, 0x09U, 0x29U, 0xF6U, 0x20U,
|
||||
0xC0U, 0x88U, 0x7EU, 0x09U, 0x03U,
|
||||
0x20U, 0x54U, 0x54U, 0x79U, 0x41U,
|
||||
0x00U, 0x00U, 0x44U, 0x7DU, 0x41U,
|
||||
0x30U, 0x48U, 0x48U, 0x4AU, 0x32U,
|
||||
0x38U, 0x40U, 0x40U, 0x22U, 0x7AU,
|
||||
0x00U, 0x7AU, 0x0AU, 0x0AU, 0x72U,
|
||||
0x7DU, 0x0DU, 0x19U, 0x31U, 0x7DU,
|
||||
0x26U, 0x29U, 0x29U, 0x2FU, 0x28U,
|
||||
0x26U, 0x29U, 0x29U, 0x29U, 0x26U,
|
||||
0x30U, 0x48U, 0x4DU, 0x40U, 0x20U,
|
||||
0x38U, 0x08U, 0x08U, 0x08U, 0x08U,
|
||||
0x08U, 0x08U, 0x08U, 0x08U, 0x38U,
|
||||
0x2FU, 0x10U, 0xC8U, 0xACU, 0xBAU,
|
||||
0x2FU, 0x10U, 0x28U, 0x34U, 0xFAU,
|
||||
0x00U, 0x00U, 0x7BU, 0x00U, 0x00U,
|
||||
0x08U, 0x14U, 0x2AU, 0x14U, 0x22U,
|
||||
0x22U, 0x14U, 0x2AU, 0x14U, 0x08U,
|
||||
0xAAU, 0x00U, 0x55U, 0x00U, 0xAAU,
|
||||
0xAAU, 0x55U, 0xAAU, 0x55U, 0xAAU,
|
||||
0x00U, 0x00U, 0x00U, 0xFFU, 0x00U,
|
||||
0x10U, 0x10U, 0x10U, 0xFFU, 0x00U,
|
||||
0x14U, 0x14U, 0x14U, 0xFFU, 0x00U,
|
||||
0x10U, 0x10U, 0xFFU, 0x00U, 0xFFU,
|
||||
0x10U, 0x10U, 0xF0U, 0x10U, 0xF0U,
|
||||
0x14U, 0x14U, 0x14U, 0xFCU, 0x00U,
|
||||
0x14U, 0x14U, 0xF7U, 0x00U, 0xFFU,
|
||||
0x00U, 0x00U, 0xFFU, 0x00U, 0xFFU,
|
||||
0x14U, 0x14U, 0xF4U, 0x04U, 0xFCU,
|
||||
0x14U, 0x14U, 0x17U, 0x10U, 0x1FU,
|
||||
0x10U, 0x10U, 0x1FU, 0x10U, 0x1FU,
|
||||
0x14U, 0x14U, 0x14U, 0x1FU, 0x00U,
|
||||
0x10U, 0x10U, 0x10U, 0xF0U, 0x00U,
|
||||
0x00U, 0x00U, 0x00U, 0x1FU, 0x10U,
|
||||
0x10U, 0x10U, 0x10U, 0x1FU, 0x10U,
|
||||
0x10U, 0x10U, 0x10U, 0xF0U, 0x10U,
|
||||
0x00U, 0x00U, 0x00U, 0xFFU, 0x10U,
|
||||
0x10U, 0x10U, 0x10U, 0x10U, 0x10U,
|
||||
0x10U, 0x10U, 0x10U, 0xFFU, 0x10U,
|
||||
0x00U, 0x00U, 0x00U, 0xFFU, 0x14U,
|
||||
0x00U, 0x00U, 0xFFU, 0x00U, 0xFFU,
|
||||
0x00U, 0x00U, 0x1FU, 0x10U, 0x17U,
|
||||
0x00U, 0x00U, 0xFCU, 0x04U, 0xF4U,
|
||||
0x14U, 0x14U, 0x17U, 0x10U, 0x17U,
|
||||
0x14U, 0x14U, 0xF4U, 0x04U, 0xF4U,
|
||||
0x00U, 0x00U, 0xFFU, 0x00U, 0xF7U,
|
||||
0x14U, 0x14U, 0x14U, 0x14U, 0x14U,
|
||||
0x14U, 0x14U, 0xF7U, 0x00U, 0xF7U,
|
||||
0x14U, 0x14U, 0x14U, 0x17U, 0x14U,
|
||||
0x10U, 0x10U, 0x1FU, 0x10U, 0x1FU,
|
||||
0x14U, 0x14U, 0x14U, 0xF4U, 0x14U,
|
||||
0x10U, 0x10U, 0xF0U, 0x10U, 0xF0U,
|
||||
0x00U, 0x00U, 0x1FU, 0x10U, 0x1FU,
|
||||
0x00U, 0x00U, 0x00U, 0x1FU, 0x14U,
|
||||
0x00U, 0x00U, 0x00U, 0xFCU, 0x14U,
|
||||
0x00U, 0x00U, 0xF0U, 0x10U, 0xF0U,
|
||||
0x10U, 0x10U, 0xFFU, 0x10U, 0xFFU,
|
||||
0x14U, 0x14U, 0x14U, 0xFFU, 0x14U,
|
||||
0x10U, 0x10U, 0x10U, 0x1FU, 0x00U,
|
||||
0x00U, 0x00U, 0x00U, 0xF0U, 0x10U,
|
||||
0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU,
|
||||
0xF0U, 0xF0U, 0xF0U, 0xF0U, 0xF0U,
|
||||
0xFFU, 0xFFU, 0xFFU, 0x00U, 0x00U,
|
||||
0x00U, 0x00U, 0x00U, 0xFFU, 0xFFU,
|
||||
0x0FU, 0x0FU, 0x0FU, 0x0FU, 0x0FU,
|
||||
0x38U, 0x44U, 0x44U, 0x38U, 0x44U,
|
||||
0x7CU, 0x2AU, 0x2AU, 0x3EU, 0x14U,
|
||||
0x7EU, 0x02U, 0x02U, 0x06U, 0x06U,
|
||||
0x02U, 0x7EU, 0x02U, 0x7EU, 0x02U,
|
||||
0x63U, 0x55U, 0x49U, 0x41U, 0x63U,
|
||||
0x38U, 0x44U, 0x44U, 0x3CU, 0x04U,
|
||||
0x40U, 0x7EU, 0x20U, 0x1EU, 0x20U,
|
||||
0x06U, 0x02U, 0x7EU, 0x02U, 0x02U,
|
||||
0x99U, 0xA5U, 0xE7U, 0xA5U, 0x99U,
|
||||
0x1CU, 0x2AU, 0x49U, 0x2AU, 0x1CU,
|
||||
0x4CU, 0x72U, 0x01U, 0x72U, 0x4CU,
|
||||
0x30U, 0x4AU, 0x4DU, 0x4DU, 0x30U,
|
||||
0x30U, 0x48U, 0x78U, 0x48U, 0x30U,
|
||||
0xBCU, 0x62U, 0x5AU, 0x46U, 0x3DU,
|
||||
0x3EU, 0x49U, 0x49U, 0x49U, 0x00U,
|
||||
0x7EU, 0x01U, 0x01U, 0x01U, 0x7EU,
|
||||
0x2AU, 0x2AU, 0x2AU, 0x2AU, 0x2AU,
|
||||
0x44U, 0x44U, 0x5FU, 0x44U, 0x44U,
|
||||
0x40U, 0x51U, 0x4AU, 0x44U, 0x40U,
|
||||
0x40U, 0x44U, 0x4AU, 0x51U, 0x40U,
|
||||
0x00U, 0x00U, 0xFFU, 0x01U, 0x03U,
|
||||
0xE0U, 0x80U, 0xFFU, 0x00U, 0x00U,
|
||||
0x08U, 0x08U, 0x6BU, 0x6BU, 0x08U,
|
||||
0x36U, 0x12U, 0x36U, 0x24U, 0x36U,
|
||||
0x06U, 0x0FU, 0x09U, 0x0FU, 0x06U,
|
||||
0x00U, 0x00U, 0x18U, 0x18U, 0x00U,
|
||||
0x00U, 0x00U, 0x10U, 0x10U, 0x00U,
|
||||
0x30U, 0x40U, 0xFFU, 0x01U, 0x01U,
|
||||
0x00U, 0x1FU, 0x01U, 0x01U, 0x1EU,
|
||||
0x00U, 0x19U, 0x1DU, 0x17U, 0x12U,
|
||||
0x00U, 0x3CU, 0x3CU, 0x3CU, 0x3CU,
|
||||
0x00U, 0x00U, 0x00U, 0x00U, 0x00U};
|
||||
|
||||
// Arduino Compatible Macro
|
||||
#define _BV(bit) (1 << (bit))
|
||||
|
||||
|
||||
|
||||
CI2COLED::CI2COLED() :
|
||||
m_i2c(),
|
||||
m_oledBuffer(NULL)
|
||||
{
|
||||
m_oledBuffer = new uint8_t[OLED_BUFFER_SIZE];
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
void CI2COLED::init()
|
||||
{
|
||||
m_i2c.init();
|
||||
|
||||
// Initialise the VG-6432TSWEG02 OLED display
|
||||
// Taken from https://datasheet.lcsc.com/szlcsc/1912111437_WiseChip-VG-6432TSWAG01-IIC-sh1106_C194312.pdf
|
||||
|
||||
sendCommand(0xAEU); // Display off
|
||||
|
||||
sendCommand(0x00U); // Set lower column address
|
||||
sendCommand(0x12U); // Set higher column address
|
||||
|
||||
sendCommand(0x00U); // Set display start line
|
||||
|
||||
sendCommand(0xB0U); // Set page address
|
||||
|
||||
sendCommand(0x81U, 0x4FU); // Contract control, 128
|
||||
|
||||
sendCommand(0xA1U); // Set segment remap
|
||||
|
||||
sendCommand(0xA6U); // Normal/reverse
|
||||
|
||||
sendCommand(0xA8U, 0x1FU); // Multiplex ratio, duty = 1/32
|
||||
|
||||
sendCommand(0xC8U); // Com scan direction
|
||||
|
||||
sendCommand(0xD3U, 0x00U); // Set display offset
|
||||
|
||||
sendCommand(0xD5U, 0x80U); // Set osc division
|
||||
|
||||
sendCommand(0xD9U, 0x1FU); // Set pre-charge period
|
||||
|
||||
sendCommand(0xDAU, 0x12U); // Set COM pins
|
||||
|
||||
sendCommand(0xDBU, 0x40U); // Set vcomh
|
||||
|
||||
sendCommand(0x8DU, 0x14U); // Set charge pump enable
|
||||
|
||||
sendCommand(0xAFU); // Display on
|
||||
}
|
||||
|
||||
void CI2COLED::setMode(int state)
|
||||
{
|
||||
clear();
|
||||
|
||||
switch (MMDVM_STATE(state)) {
|
||||
case STATE_IDLE:
|
||||
write("Idle");
|
||||
break;
|
||||
case STATE_DSTAR:
|
||||
write("D-Star");
|
||||
break;
|
||||
case STATE_DMR:
|
||||
write("DMR");
|
||||
break;
|
||||
case STATE_YSF:
|
||||
write("YSF");
|
||||
break;
|
||||
case STATE_P25:
|
||||
write("P25");
|
||||
break;
|
||||
case STATE_NXDN:
|
||||
write("NXDN");
|
||||
break;
|
||||
case STATE_FM:
|
||||
write("FM");
|
||||
break;
|
||||
case STATE_M17:
|
||||
write("M17");
|
||||
break;
|
||||
case STATE_POCSAG:
|
||||
write("POCSAG");
|
||||
break;
|
||||
case STATE_AX25:
|
||||
write("AX.25");
|
||||
break;
|
||||
default:
|
||||
write("Calibrate");
|
||||
break;
|
||||
}
|
||||
|
||||
display();
|
||||
}
|
||||
|
||||
void CI2COLED::sendCommand(uint8_t c0, uint8_t c1)
|
||||
{
|
||||
uint8_t buff[3U];
|
||||
|
||||
buff[0U] = SSD_Command_Mode;
|
||||
buff[1U] = c0;
|
||||
buff[2U] = c1;
|
||||
|
||||
// Write Data on I2C
|
||||
m_i2c.write(OLED_ADDRESS, buff, 3U);
|
||||
}
|
||||
|
||||
void CI2COLED::sendCommand(uint8_t c)
|
||||
{
|
||||
uint8_t buff[2U];
|
||||
|
||||
buff[0U] = SSD_Command_Mode;
|
||||
buff[1U] = c;
|
||||
|
||||
// Write Data on I2C
|
||||
m_i2c.write(OLED_ADDRESS, buff, 2U);
|
||||
}
|
||||
|
||||
void CI2COLED::sendData(const uint8_t* data, uint16_t length)
|
||||
{
|
||||
uint8_t buff[20U];
|
||||
|
||||
buff[0U] = SSD_Data_Mode;
|
||||
::memcpy(buff + 1U, data, length * sizeof(uint8_t));
|
||||
|
||||
// Write Data on I2C
|
||||
m_i2c.write(OLED_ADDRESS, buff, length + 1U);
|
||||
}
|
||||
|
||||
void CI2COLED::clear()
|
||||
{
|
||||
::memset(m_oledBuffer, 0x00U, OLED_BUFFER_SIZE);
|
||||
}
|
||||
|
||||
void CI2COLED::write(const char* text)
|
||||
{
|
||||
size_t len = ::strlen(text);
|
||||
|
||||
uint16_t scale = OLED_WIDTH / (len * (CHAR_WIDTH + 1U));
|
||||
if (scale == 0U) scale = 1U;
|
||||
|
||||
uint8_t charHeight = CHAR_HEIGHT * scale;
|
||||
uint8_t charWidth = (CHAR_WIDTH + 1U) * scale;
|
||||
|
||||
uint8_t x = (OLED_HEIGHT - charHeight) / 2U;
|
||||
uint8_t y = (OLED_WIDTH - charWidth) / 2U;
|
||||
|
||||
for (size_t i = 0U; i < len; i++) {
|
||||
write(x, y, text[i], scale);
|
||||
y += charWidth;
|
||||
}
|
||||
}
|
||||
|
||||
void CI2COLED::write(uint8_t x, uint8_t y, char c, uint8_t size)
|
||||
{
|
||||
for (uint8_t i = 0U; i < 6U; i++) {
|
||||
uint8_t line;
|
||||
if (i == 5U)
|
||||
line = 0U;
|
||||
else
|
||||
line = FONT[(c * 5U) + i];
|
||||
|
||||
for (uint8_t j = 0U; j < 8U; j++) {
|
||||
if (line & 0x1U) {
|
||||
if (size == 1U) // default size
|
||||
drawPixel(x + i, y + j);
|
||||
else // big size
|
||||
fillRect(x + (i * size), y + (j * size), size, size);
|
||||
}
|
||||
|
||||
line >>= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CI2COLED::fillRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height)
|
||||
{
|
||||
for (uint8_t i = x; i < (x + height - 1U); i++) {
|
||||
for (uint8_t j = y; j < (y + width - 1U); j++)
|
||||
drawPixel(i, j);
|
||||
}
|
||||
}
|
||||
|
||||
void CI2COLED::drawPixel(uint8_t x, uint8_t y)
|
||||
{
|
||||
// Get where to do the change in the buffer
|
||||
uint8_t* p = m_oledBuffer + (x + (y / 8U) * OLED_WIDTH);
|
||||
|
||||
// x is which column
|
||||
*p |= _BV((y % 8U));
|
||||
}
|
||||
|
||||
void CI2COLED::display()
|
||||
{
|
||||
sendCommand(SSD1306_Set_Lower_Column_Start_Address | 0x00U); // Low col = 0
|
||||
sendCommand(SSD1306_Set_Higher_Column_Start_Address | 0x00U); // High col = 0
|
||||
sendCommand(SSD1306_Set_Start_Line | 0x00U); // Line #0
|
||||
|
||||
// loop trough all OLED buffer and send a bunch of 16 data byte in one transmission
|
||||
for (uint16_t i = 0U; i < OLED_BUFFER_SIZE; i += 16U)
|
||||
sendData(m_oledBuffer + i, 16U);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2020,2021 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 "I2C3.h"
|
||||
|
||||
class CI2COLED {
|
||||
public:
|
||||
CI2COLED();
|
||||
|
||||
void init();
|
||||
|
||||
void setMode(int state);
|
||||
|
||||
private:
|
||||
CI2C3 m_i2c;
|
||||
uint8_t* m_oledBuffer;
|
||||
|
||||
void write(const char* text);
|
||||
void write(uint8_t x, uint8_t y, char c, uint8_t size);
|
||||
void drawPixel(uint8_t x, uint8_t y);
|
||||
void fillRect(uint8_t x, uint8_t y, uint8_t width, uint8_t height);
|
||||
void clear();
|
||||
void display();
|
||||
|
||||
void sendCommand(uint8_t c);
|
||||
void sendCommand(uint8_t c0, uint8_t c1);
|
||||
void sendData(const uint8_t* c, uint16_t length);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -760,6 +760,10 @@ void CIO::setMode(MMDVM_STATE state)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(MODE_OLED)
|
||||
oled.setMode(state);
|
||||
#endif
|
||||
|
||||
m_modemState = state;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2016 by Jim McLaughlin KI6ZUM
|
||||
* Copyright (C) 2016,2017,2018 by Andy Uribe CA6JAU
|
||||
* Copyright (C) 2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2017,2018,2020,2021 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2019,2020 by BG5HHP
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -190,6 +190,10 @@ void CIO::initInt()
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(MODE_OLED)
|
||||
oled.init();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CIO::startInt()
|
||||
|
||||
+8
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* Copyright (C) 2016 by Jim McLaughlin KI6ZUM
|
||||
* Copyright (C) 2016, 2017 by Andy Uribe CA6JAU
|
||||
* Copyright (C) 2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2017,2018,2020,2021 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2017 by Wojciech Krutnik N0CALL
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -217,6 +217,7 @@ static inline void GPIOInit()
|
||||
GPIOConfigPin(PORT_LED, PIN_LED, GPIO_CRL_MODE0_1);
|
||||
GPIOConfigPin(PORT_COS, PIN_COS, GPIO_CRL_CNF0_1);
|
||||
|
||||
#if defined(MODE_LEDS)
|
||||
GPIOConfigPin(PORT_DSTAR, PIN_DSTAR, GPIO_CRL_MODE0_1);
|
||||
GPIOConfigPin(PORT_DMR, PIN_DMR, GPIO_CRL_MODE0_1);
|
||||
GPIOConfigPin(PORT_YSF, PIN_YSF, GPIO_CRL_MODE0_1);
|
||||
@@ -229,6 +230,7 @@ static inline void GPIOInit()
|
||||
#endif
|
||||
#if !defined(USE_ALTERNATE_POCSAG_LEDS)
|
||||
GPIOConfigPin(PORT_POCSAG, PIN_POCSAG, GPIO_CRL_MODE0_1);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
GPIOConfigPin(PORT_RX, PIN_RX, 0);
|
||||
@@ -357,6 +359,9 @@ void CIO::initInt()
|
||||
#if defined(STM32F1_POG)
|
||||
FancyLEDEffect();
|
||||
#endif
|
||||
#if defined(MODE_OLED)
|
||||
oled.init();
|
||||
#endif
|
||||
}
|
||||
|
||||
void CIO::startInt()
|
||||
@@ -421,6 +426,7 @@ void CIO::setCOSInt(bool on)
|
||||
BB_COSLED = !!on;
|
||||
}
|
||||
|
||||
#if defined(MODE_LEDS)
|
||||
void CIO::setDStarInt(bool on)
|
||||
{
|
||||
BB_DSTAR = !!on;
|
||||
@@ -478,6 +484,7 @@ void CIO::setFMInt(bool on)
|
||||
BB_YSF = !!on;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
void CIO::delayInt(unsigned int dly)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2017,2018,2020,2021 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016 by Mathis Schmieder DB9MAT
|
||||
* Copyright (C) 2016 by Colin Durbridge G4EML
|
||||
*
|
||||
@@ -41,6 +41,10 @@ bool m_duplex = true;
|
||||
bool m_tx = false;
|
||||
bool m_dcd = false;
|
||||
|
||||
#if defined(MODE_OLED)
|
||||
CI2COLED oled;
|
||||
#endif
|
||||
|
||||
#if defined(MODE_DSTAR)
|
||||
CDStarRX dstarRX;
|
||||
CDStarTX dstarTX;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2017,2018,2020,2021 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2016 by Colin Durbridge G4EML
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -38,6 +38,10 @@ bool m_duplex = true;
|
||||
bool m_tx = false;
|
||||
bool m_dcd = false;
|
||||
|
||||
#if defined(MODE_OLED)
|
||||
CI2COLED oled;
|
||||
#endif
|
||||
|
||||
#if defined(MODE_DSTAR)
|
||||
CDStarRX dstarRX;
|
||||
CDStarTX dstarTX;
|
||||
|
||||
+5
-49
@@ -84,7 +84,6 @@ const uint8_t MMDVM_ACK = 0x70U;
|
||||
const uint8_t MMDVM_NAK = 0x7FU;
|
||||
|
||||
const uint8_t MMDVM_SERIAL_DATA = 0x80U;
|
||||
const uint8_t MMDVM_I2C_DATA = 0x81U;
|
||||
|
||||
const uint8_t MMDVM_TRANSPARENT = 0x90U;
|
||||
const uint8_t MMDVM_QSO_INFO = 0x91U;
|
||||
@@ -134,6 +133,7 @@ const uint8_t PROTOCOL_VERSION = 2U;
|
||||
const int MAX_SERIAL_DATA = 250;
|
||||
const uint16_t MAX_SERIAL_COUNT = 100U;
|
||||
|
||||
|
||||
CSerialPort::CSerialPort() :
|
||||
m_buffer(),
|
||||
m_ptr(0U),
|
||||
@@ -141,8 +141,7 @@ m_len(0U),
|
||||
m_debug(false),
|
||||
m_serialData(),
|
||||
m_lastSerialAvail(0),
|
||||
m_lastSerialAvailCount(0U),
|
||||
m_i2CData()
|
||||
m_lastSerialAvailCount(0U)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -859,9 +858,6 @@ void CSerialPort::start()
|
||||
#if defined(SERIAL_REPEATER)
|
||||
beginInt(3U, 9600);
|
||||
#endif
|
||||
#if defined(I2C_REPEATER)
|
||||
beginInt(10U, 9600);
|
||||
#endif
|
||||
}
|
||||
|
||||
void CSerialPort::process()
|
||||
@@ -946,22 +942,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)
|
||||
@@ -1372,14 +1352,6 @@ void CSerialPort::processMessage(uint8_t type, const uint8_t* buffer, uint16_t l
|
||||
break;
|
||||
#endif
|
||||
|
||||
#if defined(I2C_REPEATER)
|
||||
case MMDVM_I2C_DATA: {
|
||||
for (uint16_t i = 0U; i < length; i++)
|
||||
m_i2CData.put(buffer[i]);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
// Handle this, send a NAK back
|
||||
sendNAK(1U);
|
||||
@@ -1872,25 +1844,6 @@ void CSerialPort::writeSerialData(const uint8_t* data, uint8_t length)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(I2C_REPEATER)
|
||||
void CSerialPort::writeI2CData(const uint8_t* data, uint8_t length)
|
||||
{
|
||||
uint8_t reply[255U];
|
||||
|
||||
reply[0U] = MMDVM_FRAME_START;
|
||||
reply[1U] = 0U;
|
||||
reply[2U] = MMDVM_I2C_DATA;
|
||||
|
||||
uint8_t count = 3U;
|
||||
for (uint8_t i = 0U; i < length; i++, count++)
|
||||
reply[count] = data[i];
|
||||
|
||||
reply[1U] = count;
|
||||
|
||||
writeInt(1U, reply, count);
|
||||
}
|
||||
#endif
|
||||
|
||||
void CSerialPort::writeCalData(const uint8_t* data, uint8_t length)
|
||||
{
|
||||
if (m_modemState != STATE_DSTARCAL)
|
||||
@@ -2063,6 +2016,9 @@ void CSerialPort::writeDebug(const char* text, int16_t n1, int16_t n2, int16_t n
|
||||
|
||||
void CSerialPort::writeDebugDump(const uint8_t* data, uint16_t length)
|
||||
{
|
||||
if (length > 500U)
|
||||
length = 500U;
|
||||
|
||||
uint8_t reply[512U];
|
||||
|
||||
reply[0U] = MMDVM_FRAME_START;
|
||||
|
||||
@@ -85,10 +85,6 @@ public:
|
||||
void writeSerialData(const uint8_t* data, uint8_t length);
|
||||
#endif
|
||||
|
||||
#if defined(I2C_REPEATER)
|
||||
void writeI2CData(const uint8_t* data, uint8_t length);
|
||||
#endif
|
||||
|
||||
void writeCalData(const uint8_t* data, uint8_t length);
|
||||
void writeRSSIData(const uint8_t* data, uint8_t length);
|
||||
|
||||
@@ -107,7 +103,6 @@ private:
|
||||
CRingBuffer<uint8_t> m_serialData;
|
||||
int m_lastSerialAvail;
|
||||
uint16_t m_lastSerialAvailCount;
|
||||
CRingBuffer<uint8_t> m_i2CData;
|
||||
|
||||
void sendACK();
|
||||
void sendNAK(uint8_t err);
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
###############################################################################
|
||||
#
|
||||
# mmdvmmenu.sh
|
||||
#
|
||||
# Copyright (C) 2016 by Paul Nannery KC2VRJ
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# On a Linux based system, such as a Raspberry Pi, this script will perform
|
||||
# Modification of the Config.h file for most options. It makes a Back up when
|
||||
# you start the script if none is present. You must recompile and load firmware
|
||||
# onto the Arduino Due if changes are made.
|
||||
#
|
||||
###############################################################################
|
||||
#
|
||||
# CONFIGURATION
|
||||
#
|
||||
# Location of Config.h
|
||||
conf=Config.h
|
||||
#Location of backup file
|
||||
confbak=Config.h.bak
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Do not edit below here
|
||||
#
|
||||
###############################################################################
|
||||
|
||||
|
||||
|
||||
# Check for backup file and make one if not present
|
||||
|
||||
if [ ! -f $confbak ];then
|
||||
|
||||
cp -f $conf $confbak
|
||||
|
||||
fi
|
||||
|
||||
while :
|
||||
do
|
||||
clear
|
||||
cat<<EOF
|
||||
==============================================================
|
||||
MMDVM Configuration Options
|
||||
--------------------------------------------------------------
|
||||
Please enter your choice:
|
||||
|
||||
(1) Enable 12.000 MHZ Clock
|
||||
(2) Enable 12.288 MHZ Clock
|
||||
(3) Enable 14.400 MHz Clock
|
||||
(4) Enable 19.200 MHz Clock
|
||||
(5) Use the COS to lockout the modem
|
||||
(6) Use pins to output the current mode
|
||||
(7) Use layout for the PAPA board
|
||||
(8) Use layout for ZUM V1.0 and V1.0.1 boards
|
||||
(9) Use layout for SP8NTH board
|
||||
(0) Use modem as display driver
|
||||
(A) Return to Default
|
||||
|
||||
(Q)uit
|
||||
---------------------------------------------------------------
|
||||
EOF
|
||||
read -n1 -s
|
||||
case "$REPLY" in
|
||||
"1") sed -e 's/\/\/ #define EXTERNAL_OSC 12000000/#define EXTERNAL_OSC 12000000/' $conf > $conf.tmp && mv -f $conf.tmp $conf && echo "12.000 MHz clock enabled";;
|
||||
"2") sed -e 's/\/\/ #define EXTERNAL_OSC 12288000/#define EXTERNAL_OSC 12288000/' $conf > $conf.tmp && mv -f $conf.tmp $conf && echo "12.288 MHz clock enabled";;
|
||||
"3") sed -e 's/\/\/ #define EXTERNAL_OSC 14400000/#define EXTERNAL_OSC 14400000/' $conf > $conf.tmp && mv -f $conf.tmp $conf && echo "14.400 MHz clock enabled";;
|
||||
"4") sed -e 's/\/\/ #define EXTERNAL_OSC 19200000/#define EXTERNAL_OSC 19200000/' $conf > $conf.tmp && mv -f $conf.tmp $conf && echo "19.200 MHz clock enabled";;
|
||||
"5") sed -e 's/\/\/ #define USE_COS_AS_LOCKOUT /#define USE_COS_AS_LOCKOUT/' $conf > $conf.tmp && mv -f $conf.tmp $conf && echo "COS as Lockout enabled";;
|
||||
"6") sed -e 's/\/\/ #define MODE_LEDS/#define MODE_LEDS/' $conf > $conf.tmp && mv -f $conf.tmp $conf && echo "Mode pins enabled";;
|
||||
"7") sed -e 's/\/\/ #define ARDUINO_DUE_PAPA/#define ARDUINO_DUE_PAPA/' $conf > $conf.tmp && mv -f $conf.tmp $conf && echo "Layout for the PAPA board enabled";;
|
||||
"8") sed -e 's/\/\/ #define ARDUINO_DUE_ZUM_V10/#define ARDUINO_DUE_ZUM_V10/' $conf > $conf.tmp && mv -f $conf.tmp $conf && echo "Layout for ZUM V1.0 and V1.0.1 boards enabled";;
|
||||
"9") sed -e 's/\/\/ #define ARDUINO_DUE_NTH/#define ARDUINO_DUE_NTH/' $conf > $conf.tmp && mv -f $conf.tmp $conf && echo "Layout for SP8NTH board enabled";;
|
||||
"0") sed -e 's/\/\/ #define SERIAL_REPEATER/#define SERIAL_REPEATER/' $conf > $conf.tmp && mv -f $conf.tmp $conf && echo "Modem display driver enabled";;
|
||||
"A") mv -f $confbak $conf ;;
|
||||
"a") mv -f $confbak $conf ;;
|
||||
"Q") echo "If any changes are made you need to (re-)upload the firmware to MMDVM" && exit;;
|
||||
"q") echo "If any changes are made you need to (re-)upload the firmware to MMDVM" && exit;;
|
||||
* ) echo "invalid option" ;;
|
||||
esac
|
||||
sleep 1
|
||||
done
|
||||
Reference in New Issue
Block a user