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:
parent
2a45e7a8d4
commit
e16d5f33d1
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user