diff --git a/I2CPort.cpp b/I2CPort.cpp index b845868..be7ffea 100644 --- a/I2CPort.cpp +++ b/I2CPort.cpp @@ -35,7 +35,10 @@ const uint16_t I2C_ADDR = 0U; // XXX FIXME CI2CPort::CI2CPort(uint8_t n) : m_n(n), -m_ok(false) +m_ok(false), +m_fifo(), +m_fifoHead(0U), +m_fifoTail(0U) { } @@ -69,14 +72,14 @@ bool CI2CPort::init() NVIC_InitTypeDef NVIC_InitStructure; I2C_InitTypeDef I2C_InitStructure; - RCC_APB1PeriphClockCmd(i2CClock, ENABLE); - RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); - RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); + RCC_AHB1PeriphClockCmd(i2CClock, ENABLE); + RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); + // RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_AFIO, ENABLE); // Configure I2C GPIOs GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_Init(GPIOB, &GPIO_InitStructure); // Configure the I2C event interrupt @@ -107,25 +110,48 @@ bool CI2CPort::init() I2C_ITConfig(i2CPort, I2C_IT_BUF, ENABLE); I2C_ITConfig(i2CPort, I2C_IT_ERR, ENABLE); + m_fifoHead = 0U; + m_fifoTail = 0U; + m_ok = true; return true; } -uint8_t CI2CPort::writeCommand(const uint8_t* data, uint8_t length) +uint8_t CI2CPort::write(const uint8_t* data, uint8_t length) { if (!m_ok) return 6U; - return 6U; + for (uint16_t i = 0U; i < length; i++) + fifoPut(data[i]); + + return 0U; } -uint8_t CI2CPort::writeData(const uint8_t* data, uint8_t length) +uint16_t CI2CPort::fifoLevel() { - if (!m_ok) - return 6U; + uint32_t tail = m_fifoTail; + uint32_t head = m_fifoHead; - return 6U; + if (tail > head) + return I2C_TX_FIFO_SIZE + head - tail; + else + return head - tail; +} + +bool CI2CPort::fifoPut(uint8_t next) +{ + if (fifoLevel() >= I2C_TX_FIFO_SIZE) + return false; + + m_fifo[m_fifoHead] = next; + + m_fifoHead++; + if (m_fifoHead >= I2C_TX_FIFO_SIZE) + m_fifoHead = 0U; + + return true; } #endif diff --git a/I2CPort.h b/I2CPort.h index 7ab5cfe..a6c12be 100644 --- a/I2CPort.h +++ b/I2CPort.h @@ -25,6 +25,8 @@ #include +const uint16_t I2C_TX_FIFO_SIZE = 512U; + class CI2CPort { public: @@ -32,13 +34,17 @@ public: bool init(); - uint8_t writeCommand(const uint8_t* data, uint8_t length); - - uint8_t writeData(const uint8_t* data, uint8_t length); + uint8_t write(const uint8_t* data, uint8_t length); private: uint8_t m_n; bool m_ok; + volatile uint8_t m_fifo[I2C_TX_FIFO_SIZE]; + volatile uint16_t m_fifoHead; + volatile uint16_t m_fifoTail; + + uint16_t fifoLevel(); + bool fifoPut(uint8_t next); }; #endif diff --git a/SerialPort.cpp b/SerialPort.cpp index 64c5b80..5c01c35 100644 --- a/SerialPort.cpp +++ b/SerialPort.cpp @@ -127,9 +127,6 @@ 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(), @@ -1316,21 +1313,11 @@ void CSerialPort::processMessage(uint8_t type, const uint8_t* buffer, uint16_t l #if defined(I2C_REPEATER) case MMDVM_I2C_DATA: { - uint8_t type = buffer[0U]; - switch (type) { - case I2C_COMMAND: - err = i2c1.writeCommand(buffer + 1U, length - 1U); - break; - case I2C_DATA: - err = i2c1.writeData(buffer + 1U, length - 1U); - break; - default: - DEBUG2("Received invalid I2C type", type); - err = 4U; - break; - } - if (err != 0U) + err = i2c1.write(buffer, length); + if (err != 0U) { + DEBUG2("Received invalid I2C data", err); sendNAK(err); + } } break; #endif