2024-03-16 19:00:23 +00:00
|
|
|
//
|
|
|
|
// I2C.cpp
|
|
|
|
// Clock Signal
|
|
|
|
//
|
|
|
|
// Created by Thomas Harte on 16/03/2024.
|
|
|
|
// Copyright © 2024 Thomas Harte. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#include "I2C.hpp"
|
|
|
|
|
|
|
|
using namespace I2C;
|
|
|
|
|
|
|
|
void Bus::set_data(bool pulled) {
|
|
|
|
set_clock_data(clock_, pulled);
|
|
|
|
}
|
|
|
|
bool Bus::data() {
|
|
|
|
return data_;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Bus::set_clock(bool pulled) {
|
|
|
|
set_clock_data(pulled, data_);
|
|
|
|
}
|
|
|
|
bool Bus::clock() {
|
|
|
|
return clock_;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Bus::set_clock_data(bool clock_pulled, bool data_pulled) {
|
2024-03-17 02:02:16 +00:00
|
|
|
const bool has_new_bit = clock_pulled && !clock_;
|
2024-03-16 19:00:23 +00:00
|
|
|
clock_ = clock_pulled;
|
|
|
|
data_ = data_pulled;
|
2024-03-17 02:02:16 +00:00
|
|
|
|
|
|
|
// TODO: "Stop condition: SDA goes high after SCL (?)".
|
|
|
|
|
|
|
|
if(has_new_bit) {
|
|
|
|
// Test for a start bit.
|
|
|
|
//
|
|
|
|
// "Start condition: SDA goes low before SCL".
|
|
|
|
if(input_count_ < 0 && data_) {
|
|
|
|
input_count_ = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Accumulate if started.
|
|
|
|
if(input_count_ >= 0) {
|
|
|
|
input_ = uint16_t((input_ << 1) | (data_pulled ? 0 : 1));
|
|
|
|
++input_count_;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test for meaning.
|
|
|
|
switch(phase_) {
|
|
|
|
case Phase::AwaitingAddress:
|
|
|
|
if(input_count_ == 9) {
|
|
|
|
printf("Calling %02x?", uint8_t(input_));
|
|
|
|
|
|
|
|
auto pair = peripherals_.find(uint8_t(input_));
|
|
|
|
if(pair != peripherals_.end()) {
|
|
|
|
active_peripheral_ = pair->second;
|
|
|
|
// TODO: device found; pull data low for the next clock.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case Phase::CollectingData:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2024-03-16 19:00:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Bus::add_peripheral(Peripheral *peripheral, int address) {
|
|
|
|
peripherals_[address] = peripheral;
|
|
|
|
}
|