diff --git a/Globals.h b/Globals.h index 1e0b04c..68f0fbe 100644 --- a/Globals.h +++ b/Globals.h @@ -146,10 +146,11 @@ extern CIO io; #if defined(MODE_OLED) extern CI2COLED oled; +extern CI2CPort i2C3; #endif #if defined(I2C_REPEATER) -extern CI2CPort i2c1; +extern CI2CPort i2C1; #endif #if defined(MODE_DSTAR) diff --git a/I2COLED.cpp b/I2COLED.cpp index da3c156..4706735 100644 --- a/I2COLED.cpp +++ b/I2COLED.cpp @@ -21,6 +21,7 @@ #if defined(MODE_OLED) #include "I2COLED.h" +#include "I2CPort.h" #include "Globals.h" @@ -304,7 +305,6 @@ const uint8_t FONT[] = { CI2COLED::CI2COLED() : -m_i2c(3U), m_oledBuffer(NULL) { m_oledBuffer = new uint8_t[OLED_BUFFER_SIZE]; @@ -314,7 +314,7 @@ m_oledBuffer(NULL) bool CI2COLED::init() { - bool ret = m_i2c.init(); + bool ret = i2C3.init(); if (!ret) return false; @@ -409,7 +409,7 @@ void CI2COLED::sendCommand(uint8_t c0, uint8_t c1, uint8_t c2) buff[4U] = c2; // Write Data on I2C - m_i2c.write(buff, 5U); + i2C3.write(buff, 5U); } void CI2COLED::sendCommand(uint8_t c0, uint8_t c1) @@ -422,7 +422,7 @@ void CI2COLED::sendCommand(uint8_t c0, uint8_t c1) buff[3U] = c1; // Write Data on I2C - m_i2c.write(buff, 4U); + i2C3.write(buff, 4U); } void CI2COLED::sendCommand(uint8_t c) @@ -434,7 +434,7 @@ void CI2COLED::sendCommand(uint8_t c) buff[2U] = c; // Write Data on I2C - m_i2c.write(buff, 3U); + i2C3.write(buff, 3U); } void CI2COLED::sendData(const uint8_t* data, uint16_t length) @@ -445,8 +445,8 @@ void CI2COLED::sendData(const uint8_t* data, uint16_t length) buff[1U] = SSD_Data_Mode; // Write Data on I2C - m_i2c.write(buff, 2U); - m_i2c.write(data, length); + i2C3.write(buff, 2U); + i2C3.write(data, length); } void CI2COLED::clear() diff --git a/I2COLED.h b/I2COLED.h index 928788e..b95735d 100644 --- a/I2COLED.h +++ b/I2COLED.h @@ -25,8 +25,6 @@ #include -#include "I2CPort.h" - class CI2COLED { public: CI2COLED(); @@ -36,7 +34,6 @@ public: void setMode(int state); private: - CI2CPort m_i2c; uint8_t* m_oledBuffer; void write(const char* text); diff --git a/I2CPort.cpp b/I2CPort.cpp index be7ffea..5034ede 100644 --- a/I2CPort.cpp +++ b/I2CPort.cpp @@ -1,3 +1,4 @@ + /* * Copyright (C) 2020 by Jonathan Naylor G4KLX * @@ -30,9 +31,54 @@ #include "stm32f7xx_i2c.h" #endif +#include "Globals.h" + const uint32_t I2C_CLK_FREQ = 100000U; // XXX FIXME const uint16_t I2C_ADDR = 0U; // XXX FIXME + +extern "C" { +#if defined(I2C_REPEATER) + void I2C1_EV_IRQHandler(void) + { + i2C1.eventHandler(); + } + + void I2C1_ER_IRQHandler(void) + { + if (I2C_GetITStatus(I2C1, I2C_IT_AF)) + I2C_ClearITPendingBit(I2C1, I2C_IT_AF); + } +#endif + +#ifdef notdef + void I2C2_EV_IRQHandler(void) + { + i2C2.eventHandler(); + } + + void I2C2_ER_IRQHandler(void) + { + if (I2C_GetITStatus(I2C2, I2C_IT_AF)) + I2C_ClearITPendingBit(I2C2, I2C_IT_AF); + } +#endif + +#if defined(MODE_OLED) + void I2C3_EV_IRQHandler(void) + { + i2C3.eventHandler(); + } + + void I2C3_ER_IRQHandler(void) + { + if (I2C_GetITStatus(I2C3, I2C_IT_AF)) + I2C_ClearITPendingBit(I2C3, I2C_IT_AF); + } +#endif +} + + CI2CPort::CI2CPort(uint8_t n) : m_n(n), m_ok(false), @@ -129,6 +175,75 @@ uint8_t CI2CPort::write(const uint8_t* data, uint8_t length) return 0U; } +void CI2CPort::eventHandler() +{ + I2C_TypeDef* i2CPort = NULL; + + switch (m_n) { + case 1U: + i2CPort = I2C1; + break; + case 2U: + i2CPort = I2C2; + break; + case 3U: + i2CPort = I2C3; + break; + default: + return; + } + + uint32_t event = I2C_GetLastEvent(i2CPort); + + switch (event) { + case I2C_EVENT_SLAVE_TRANSMITTER_ADDRESS_MATCHED: + case I2C_EVENT_SLAVE_BYTE_TRANSMITTED: + if (fifoLevel() > 0U) { + I2C_SendData(i2CPort, m_fifo[m_fifoTail]); + m_fifoTail++; + if (m_fifoTail >= I2C_TX_FIFO_SIZE) + m_fifoTail = 0U; + } else + I2C_SendData(i2CPort, 0U); + break; + + case I2C_EVENT_SLAVE_STOP_DETECTED: + clearFlag(); + break; + } +} + +void CI2CPort::clearFlag() +{ + I2C_TypeDef* i2CPort = NULL; + + switch (m_n) { + case 1U: + i2CPort = I2C1; + break; + case 2U: + i2CPort = I2C2; + break; + case 3U: + i2CPort = I2C3; + break; + default: + return; + } + + // Clear ADDR flag + while((i2CPort->SR1 & I2C_SR1_ADDR) == I2C_SR1_ADDR) { + i2CPort->SR1; + i2CPort->SR2; + } + + // Clear STOPF flag + while((i2CPort->SR1 & I2C_SR1_STOPF) == I2C_SR1_STOPF) { + i2CPort->SR1; + i2CPort->CR1 |= 0x1; + } +} + uint16_t CI2CPort::fifoLevel() { uint32_t tail = m_fifoTail; diff --git a/I2CPort.h b/I2CPort.h index a6c12be..9e525ed 100644 --- a/I2CPort.h +++ b/I2CPort.h @@ -36,6 +36,8 @@ public: uint8_t write(const uint8_t* data, uint8_t length); + void eventHandler(); + private: uint8_t m_n; bool m_ok; @@ -45,6 +47,7 @@ private: uint16_t fifoLevel(); bool fifoPut(uint8_t next); + void clearFlag(); }; #endif diff --git a/IOSTM.cpp b/IOSTM.cpp index 62f6582..ab5570c 100644 --- a/IOSTM.cpp +++ b/IOSTM.cpp @@ -196,7 +196,7 @@ void CIO::initInt() #endif #if defined(I2C_REPEATER) - i2c1.init(); + i2C1.init(); #endif } diff --git a/MMDVM.cpp b/MMDVM.cpp index a4a3593..a3f39ac 100644 --- a/MMDVM.cpp +++ b/MMDVM.cpp @@ -43,10 +43,11 @@ bool m_dcd = false; #if defined(MODE_OLED) CI2COLED oled; +CI2CPort i2C3(3U); #endif #if defined(I2C_REPEATER) -CI2CPort i2c1(1U); +CI2CPort i2C1(1U); #endif #if defined(MODE_DSTAR) diff --git a/MMDVM.ino b/MMDVM.ino index cd63b42..c119fb8 100644 --- a/MMDVM.ino +++ b/MMDVM.ino @@ -40,6 +40,7 @@ bool m_dcd = false; #if defined(MODE_OLED) CI2COLED oled; +CI2CPort i2C3(3U); #endif #if defined(I2C_REPEATER) diff --git a/SerialPort.cpp b/SerialPort.cpp index 5c01c35..13c5ae8 100644 --- a/SerialPort.cpp +++ b/SerialPort.cpp @@ -1313,7 +1313,7 @@ void CSerialPort::processMessage(uint8_t type, const uint8_t* buffer, uint16_t l #if defined(I2C_REPEATER) case MMDVM_I2C_DATA: { - err = i2c1.write(buffer, length); + err = i2C1.write(buffer, length); if (err != 0U) { DEBUG2("Received invalid I2C data", err); sendNAK(err); diff --git a/Version.h b/Version.h index 0972132..7c3f717 100644 --- a/Version.h +++ b/Version.h @@ -19,7 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -#define VERSION "20201120" +#define VERSION "20201123" #endif -