1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-23 20:29:42 +00:00

Adds service requests. The microcontroller now appears to consume keyboard events.

This commit is contained in:
Thomas Harte 2021-02-15 20:33:10 -05:00
parent 2a45e7a8d4
commit e16d5f33d1
5 changed files with 40 additions and 7 deletions

View File

@ -50,6 +50,7 @@ void Bus::set_device_output(size_t device_id, bool output) {
device->adb_bus_did_observe_event(Event::Attention);
}
shift_register_ = 1;
start_target_ = 9; // Consume the stop bit before posting the next byte.
phase_ = Phase::AttentionCapture;
} else if(low_microseconds < 50.0) {
shift(1);
@ -73,15 +74,18 @@ void Bus::set_device_output(size_t device_id, bool output) {
void Bus::shift(unsigned int value) {
shift_register_ = (shift_register_ << 1) | value;
// Trigger a byte whenever a start bit hits bit 8.
if(shift_register_ & 0x100) {
// Trigger a byte whenever either:
// * a 'start bit' hits bit 8; or
// * if this was a command byte, wait for the stop bit (i.e. the start bit hits 9).
if(shift_register_ & (1 << start_target_)) {
for(auto device: devices_) {
device->adb_bus_did_observe_event(Event::Byte, uint8_t(shift_register_));
device->adb_bus_did_observe_event(Event::Byte, uint8_t(shift_register_ >> (start_target_ - 8)));
}
// Expect a real start bit only if moving from attention capture to packet
// capture. Otherwise adopt an implied start bit.
shift_register_ = phase_ == Phase::PacketCapture;
start_target_ = 8;
phase_ = Phase::PacketCapture;
}
}

View File

@ -151,6 +151,7 @@ class Bus {
double half_cycles_to_microseconds_ = 1.0;
std::vector<Device *> devices_;
unsigned int shift_register_ = 0;
unsigned int start_target_ = 8;
bool data_level_ = true;
// ADB addressing supports at most 16 devices but that doesn't include

View File

@ -132,6 +132,8 @@ bool Keyboard::set_key_pressed(Key key, bool is_pressed) {
}
#undef SetModifierBit
// Ensure service occurs.
post_service_request();
return true;
}
@ -144,6 +146,7 @@ void Keyboard::clear_all_keys() {
pressed_keys_[key] = false;
}
}
if(!pending_events_.empty()) post_service_request();
// Mark all modifiers as released.
modifiers_ |= 0xfff8;

View File

@ -27,6 +27,18 @@ void ReactiveDevice::post_response(const std::vector<uint8_t> &&response) {
}
void ReactiveDevice::advance_state(double microseconds, bool current_level) {
// First test: is a service request desired?
if(phase_ == Phase::ServiceRequestPending) {
microseconds_at_bit_ += microseconds;
if(microseconds_at_bit_ < 240.0) {
bus_.set_device_output(device_id_, false);
} else {
bus_.set_device_output(device_id_, true);
phase_ = Phase::AwaitingAttention;
}
return;
}
// Do nothing if not in the process of posting a response.
if(response_.empty()) return;
@ -50,10 +62,10 @@ void ReactiveDevice::advance_state(double microseconds, bool current_level) {
// If this is the start of the packet, wait an appropriate stop-to-start time.
if(bit_offset_ == -2) {
if(microseconds_at_bit_ < 250.0) {
if(microseconds_at_bit_ < 150.0) {
return;
}
microseconds_at_bit_ -= 250.0;
microseconds_at_bit_ -= 150.0;
++bit_offset_;
}
@ -115,8 +127,15 @@ void ReactiveDevice::adb_bus_did_observe_event(Bus::Event event, uint8_t value)
command_ = decode_command(value);
LOG(command_);
// Don't do anything if this command isn't relevant here.
// If this command doesn't apply here, but a service request is requested,
// post a service request.
if(command_.device != Command::AllDevices && command_.device != ((register3_ >> 8) & 0xf)) {
if(service_desired_) {
service_desired_ = false;
stop_has_begin_ = false;
phase_ = Phase::ServiceRequestPending;
microseconds_at_bit_ = 0.0;
}
return;
}
@ -138,6 +157,7 @@ void ReactiveDevice::adb_bus_did_observe_event(Bus::Event event, uint8_t value)
receive_bytes(2);
}
} else {
service_desired_ = false;
perform_command(command_);
}
break;
@ -156,5 +176,5 @@ void ReactiveDevice::reset() {
}
void ReactiveDevice::post_service_request() {
// TODO.
service_desired_ = true;
}

View File

@ -11,6 +11,7 @@
#include "Bus.hpp"
#include <atomic>
#include <cstddef>
#include <vector>
@ -44,14 +45,18 @@ class ReactiveDevice: public Bus::Device {
AwaitingAttention,
AwaitingCommand,
AwaitingContent,
ServiceRequestPending,
} phase_ = Phase::AwaitingAttention;
std::vector<uint8_t> content_;
size_t expected_content_size_ = 0;
Command command_;
bool stop_has_begin_ = false;
uint16_t register3_;
const uint8_t default_adb_device_id_;
std::atomic<bool> service_desired_ = false;
void reset();
};