mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +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);
|
device->adb_bus_did_observe_event(Event::Attention);
|
||||||
}
|
}
|
||||||
shift_register_ = 1;
|
shift_register_ = 1;
|
||||||
|
start_target_ = 9; // Consume the stop bit before posting the next byte.
|
||||||
phase_ = Phase::AttentionCapture;
|
phase_ = Phase::AttentionCapture;
|
||||||
} else if(low_microseconds < 50.0) {
|
} else if(low_microseconds < 50.0) {
|
||||||
shift(1);
|
shift(1);
|
||||||
@ -73,15 +74,18 @@ void Bus::set_device_output(size_t device_id, bool output) {
|
|||||||
void Bus::shift(unsigned int value) {
|
void Bus::shift(unsigned int value) {
|
||||||
shift_register_ = (shift_register_ << 1) | value;
|
shift_register_ = (shift_register_ << 1) | value;
|
||||||
|
|
||||||
// Trigger a byte whenever a start bit hits bit 8.
|
// Trigger a byte whenever either:
|
||||||
if(shift_register_ & 0x100) {
|
// * 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_) {
|
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
|
// Expect a real start bit only if moving from attention capture to packet
|
||||||
// capture. Otherwise adopt an implied start bit.
|
// capture. Otherwise adopt an implied start bit.
|
||||||
shift_register_ = phase_ == Phase::PacketCapture;
|
shift_register_ = phase_ == Phase::PacketCapture;
|
||||||
|
start_target_ = 8;
|
||||||
phase_ = Phase::PacketCapture;
|
phase_ = Phase::PacketCapture;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,6 +151,7 @@ class Bus {
|
|||||||
double half_cycles_to_microseconds_ = 1.0;
|
double half_cycles_to_microseconds_ = 1.0;
|
||||||
std::vector<Device *> devices_;
|
std::vector<Device *> devices_;
|
||||||
unsigned int shift_register_ = 0;
|
unsigned int shift_register_ = 0;
|
||||||
|
unsigned int start_target_ = 8;
|
||||||
bool data_level_ = true;
|
bool data_level_ = true;
|
||||||
|
|
||||||
// ADB addressing supports at most 16 devices but that doesn't include
|
// 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
|
#undef SetModifierBit
|
||||||
|
|
||||||
|
// Ensure service occurs.
|
||||||
|
post_service_request();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,6 +146,7 @@ void Keyboard::clear_all_keys() {
|
|||||||
pressed_keys_[key] = false;
|
pressed_keys_[key] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(!pending_events_.empty()) post_service_request();
|
||||||
|
|
||||||
// Mark all modifiers as released.
|
// Mark all modifiers as released.
|
||||||
modifiers_ |= 0xfff8;
|
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) {
|
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.
|
// Do nothing if not in the process of posting a response.
|
||||||
if(response_.empty()) return;
|
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 this is the start of the packet, wait an appropriate stop-to-start time.
|
||||||
if(bit_offset_ == -2) {
|
if(bit_offset_ == -2) {
|
||||||
if(microseconds_at_bit_ < 250.0) {
|
if(microseconds_at_bit_ < 150.0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
microseconds_at_bit_ -= 250.0;
|
microseconds_at_bit_ -= 150.0;
|
||||||
++bit_offset_;
|
++bit_offset_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,8 +127,15 @@ void ReactiveDevice::adb_bus_did_observe_event(Bus::Event event, uint8_t value)
|
|||||||
command_ = decode_command(value);
|
command_ = decode_command(value);
|
||||||
LOG(command_);
|
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(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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,6 +157,7 @@ void ReactiveDevice::adb_bus_did_observe_event(Bus::Event event, uint8_t value)
|
|||||||
receive_bytes(2);
|
receive_bytes(2);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
service_desired_ = false;
|
||||||
perform_command(command_);
|
perform_command(command_);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -156,5 +176,5 @@ void ReactiveDevice::reset() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ReactiveDevice::post_service_request() {
|
void ReactiveDevice::post_service_request() {
|
||||||
// TODO.
|
service_desired_ = true;
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include "Bus.hpp"
|
#include "Bus.hpp"
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -44,14 +45,18 @@ class ReactiveDevice: public Bus::Device {
|
|||||||
AwaitingAttention,
|
AwaitingAttention,
|
||||||
AwaitingCommand,
|
AwaitingCommand,
|
||||||
AwaitingContent,
|
AwaitingContent,
|
||||||
|
ServiceRequestPending,
|
||||||
} phase_ = Phase::AwaitingAttention;
|
} phase_ = Phase::AwaitingAttention;
|
||||||
std::vector<uint8_t> content_;
|
std::vector<uint8_t> content_;
|
||||||
size_t expected_content_size_ = 0;
|
size_t expected_content_size_ = 0;
|
||||||
Command command_;
|
Command command_;
|
||||||
|
bool stop_has_begin_ = false;
|
||||||
|
|
||||||
uint16_t register3_;
|
uint16_t register3_;
|
||||||
const uint8_t default_adb_device_id_;
|
const uint8_t default_adb_device_id_;
|
||||||
|
|
||||||
|
std::atomic<bool> service_desired_ = false;
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user