gearmulator

Emulation of classic VA synths of the late 90s/2000s that are based on Motorola 56300 family DSPs
Log | Files | Refs | Submodules | README | LICENSE

i2c.cpp (2465B)


      1 #include "i2c.h"
      2 
      3 #include <cassert>
      4 
      5 #include "dsp56kEmu/logging.h"
      6 
      7 namespace hwLib
      8 {
      9 	void I2c::masterWrite(const bool _sda, const bool _scl)
     10 	{
     11 		if(_sda != m_sda && _scl != m_scl)
     12 		{
     13 			assert(false && "only one pin should flip");
     14 			return;
     15 		}
     16 
     17 		if(_sda != m_sda)
     18 		{
     19 			m_sda = _sda;
     20 			sdaFlip(_sda);
     21 		}
     22 		else if(_scl != m_scl)
     23 		{
     24 			m_scl = _scl;
     25 			sclFlip(_scl);
     26 		}
     27 	}
     28 
     29 	std::optional<bool> I2c::masterRead(const bool _scl)
     30 	{
     31 		if(_scl == m_scl)
     32 			return {};
     33 
     34 		if(m_state != State::Start)
     35 			return {};
     36 
     37 		m_scl = _scl;
     38 
     39 		if(_scl)
     40 		{
     41 			if(m_nextBit == BitAck)
     42 			{
     43 				m_nextBit = Bit7;
     44 				return m_ackBit;	// this was returned already in onAck()
     45 			}
     46 
     47 			if(m_nextBit >= Bit0 && m_nextBit <= Bit7)
     48 			{
     49 				if(m_nextBit == Bit7)
     50 					m_byte = onReadByte();
     51 
     52 				auto res = m_byte & (1<<m_nextBit);
     53 				--m_nextBit;
     54 				return res;
     55 			}
     56 		}
     57 
     58 		return {};
     59 	}
     60 
     61 	std::optional<bool> I2c::setSdaWrite(const bool _write)
     62 	{
     63 		if(m_sdaWrite == _write)
     64 			return {};
     65 
     66 		m_sdaWrite = _write;
     67 
     68 		if(m_state != State::Start)
     69 			return {};
     70 
     71 		if(!m_sdaWrite)
     72 		{
     73 			if(m_nextBit == BitAck)
     74 			{
     75 				const auto ackBit = onAck();
     76 				if(ackBit)
     77 				{
     78 					m_ackBit = *ackBit;
     79 				}
     80 				return ackBit;
     81 			}
     82 		}
     83 		return {};
     84 	}
     85 
     86 	void I2c::onStateChanged(const State _state)
     87 	{
     88 		LOG("state: " << (_state == State::Start ? "start" : "stop"));
     89 
     90 		switch (_state)
     91 		{
     92 		case State::Stop:
     93 			m_nextBit = BitInvalid;
     94 			break;
     95 		case State::Start:
     96 			m_nextBit = Bit7;
     97 			m_byte = 0;
     98 			break;
     99 		}
    100 	}
    101 
    102 	void I2c::onStartCondition()
    103 	{
    104 		setState(State::Start);
    105 	}
    106 
    107 	void I2c::onStopCondition()
    108 	{
    109 		setState(State::Stop);
    110 	}
    111 
    112 	void I2c::onByteWritten()
    113 	{
    114 		LOG("Got byte " << HEXN(byte(), 2));
    115 	}
    116 
    117 	void I2c::sdaFlip(const bool _sda)
    118 	{
    119 		if(m_scl)
    120 		{
    121 			if(!_sda)
    122 				onStartCondition();
    123 			else
    124 				onStopCondition();
    125 		}
    126 	}
    127 
    128 	void I2c::sclFlip(const bool _scl)
    129 	{
    130 		if(_scl && m_state == State::Start)
    131 		{
    132 			if(m_nextBit >= Bit0 && m_nextBit <= Bit7)
    133 			{
    134 				LOG("next bit " << static_cast<int>(m_nextBit) << " = " << m_sda);
    135 
    136 				if(m_nextBit == Bit7)
    137 					m_byte = 0;
    138 
    139 				// data input
    140 				if(m_sda)
    141 					m_byte |= (1<<m_nextBit);
    142 
    143 				--m_nextBit;
    144 
    145 				if(m_nextBit < 0)
    146 				{
    147 					onByteWritten();
    148 				}
    149 			}
    150 			else if(m_nextBit == BitAck)
    151 			{
    152 				LOG("ACK by master=" << m_sda);
    153 				m_nextBit = 7;
    154 			}
    155 		}
    156 	}
    157 
    158 	void I2c::setState(const State _state)
    159 	{
    160 /*		if(m_state == _state)
    161 			return;
    162 */		m_state = _state;
    163 		onStateChanged(_state);
    164 	}
    165 }